package server import ( "net/http" "os" "strconv" "time" "github.com/golang-jwt/jwt/v5" "github.com/labstack/echo/v4" "github.com/labstack/gommon/log" ) const ( cookieName = "rentuuid" routeLogin = "/login" ) var validityTime = time.Now().Add(time.Hour * 24) type Claims struct { jwt.RegisteredClaims Id int `json:"id"` } func MakeAuthMiddleware(secretKey string) echo.MiddlewareFunc { return func(next echo.HandlerFunc) echo.HandlerFunc { return func(c echo.Context) error { cookie, err := c.Cookie(cookieName) if err != nil { return c.Redirect(http.StatusSeeOther, routeLogin) } signedToken := cookie.Value token, err := jwt.Parse( signedToken, func(*jwt.Token) (interface{}, error) { return []byte(secretKey), nil }, jwt.WithValidMethods([]string{jwt.SigningMethodHS256.Name}), ) if err != nil { return c.Redirect(http.StatusSeeOther, routeLogin) } if !token.Valid { return c.Redirect(http.StatusSeeOther, routeLogin) } var id int switch v := token.Claims.(jwt.MapClaims)["id"].(type) { case int: id = v case string: id, err = strconv.Atoi(token.Claims.(jwt.MapClaims)["id"].(string)) if err != nil { return c.Redirect(http.StatusSeeOther, routeLogin) } case float64: id = int(v) default: log.Errorf("id %v is of type %T", v, v) return c.Redirect(http.StatusSeeOther, routeLogin) } email, err := token.Claims.GetSubject() if err != nil { return c.Redirect(http.StatusSeeOther, routeLogin) } log.Printf("id: %d, email: %q", id, email) //c.Set("user", services.User{Id: id, Email: email, PaymentValid: paymentValid}) return next(c) } } } // refactor to use a `AuthService` func writeCookie(c echo.Context, userId int, email string) error { claims := &Claims{ jwt.RegisteredClaims{ Subject: email, ExpiresAt: jwt.NewNumericDate(validityTime), }, userId, } token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims) signedToken, err := token.SignedString(os.Getenv("SECRET_KEY")) if err != nil { return err } cookie := new(http.Cookie) cookie.Name = cookieName cookie.Value = signedToken cookie.Expires = validityTime cookie.HttpOnly = true cookie.Domain = os.Getenv("DOMAIN") cookie.Secure = true cookie.SameSite = http.SameSiteStrictMode c.SetCookie(cookie) return nil }