I’m utilizing the echo framework to check a restricted consumer route that requires a jwt. When utilizing postman it really works superb. It passes the jwt to the authorization header as a bearer token together with the cookie that’s generated after the consumer logs in. Nevertheless, when I attempt to entry the identical restricted route utilizing safari the authorization header just isn’t set to jwt. The request fails, though, I set the authorization header to equal the cookie that holds the jwt string in code.
What ought to I do?
bundle sessionmanager
import (
"errors"
"fmt"
"log"
"internet/http"
"scriptmang/drumstick/inner/backend"
"time"
"github.com/golang-jwt/jwt/v5"
"github.com/labstack/echo/v4"
)
sort UserCustomClaims struct {
Electronic mail string `json:"electronic mail"`
IsLoggedIn bool `json:"isloggedin"`
jwt.RegisteredClaims
}
func GetUserCustomClaims(t string, secretKey []byte) (*UserCustomClaims, error) {
token, err := jwt.ParseWithClaims(t, &UserCustomClaims{}, func(token *jwt.Token) (interface{}, error) {
// Validate the signing methodology
if _, okay := token.Methodology.(*jwt.SigningMethodHMAC); !okay {
return nil, fmt.Errorf("surprising signing methodology: %v", token.Header["alg"])
}
return secretKey, nil
})
if err != nil {
return nil, err
}
// Test if the token is legitimate
if claims, okay := token.Claims.(*UserCustomClaims); okay && token.Legitimate {
return claims, nil
}
return nil, fmt.Errorf("invalid token")
}
func GetEmail(c echo.Context) (string, error) {
consumer, okay := c.Get("consumer").(*jwt.Token)
if !okay {
return "", echo.NewHTTPError(http.StatusBadRequest, "error:sessionamanager: didn't convert to jwt token")
}
claims, okay := consumer.Claims.(*UserCustomClaims)
if !okay {
return "", echo.NewHTTPError(http.StatusBadRequest, "error:sessionamanager: didn't convert to customs claims sort")
}
electronic mail := claims.Electronic mail
if electronic mail == "" {
return "", echo.NewHTTPError(http.StatusBadRequest, "didn't convert electronic mail")
}
return electronic mail, nil
}
// provides consumer token to classes desk in database
func CreateToken(usr string, c echo.Context) (*jwt.Token, error) {
expirDate := time.Now().Add(time.Hour * 72).Unix()
claims := &UserCustomClaims{
Electronic mail: usr,
IsLoggedIn: true,
RegisteredClaims: jwt.RegisteredClaims{
ExpiresAt: jwt.NewNumericDate(time.Unix(expirDate, 0)),
},
}
// fmt.Printf("foo: %vn", claims.Electronic mail)
// Create token with claims
token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
return token, nil
}
bundle primary
import (
"errors"
"fmt"
"html/template"
"io"
"log"
"internet/http"
"os"
"scriptmang/drumstick/inner/sessionmanager"
"github.com/golang-jwt/jwt/v5"
echojwt "github.com/labstack/echo-jwt/v4"
"github.com/labstack/echo/v4"
"github.com/labstack/echo/v4/middleware"
)
sort TemplateManager struct {
templates *template.Template
}
func (tm *TemplateManager) Render(w io.Author, identify string, information interface{}, c echo.Context) error {
if viewContext, isMap := information.(map[string]interface{}); isMap {
viewContext["reverse"] = c.Echo().Reverse
}
err := tm.templates.ExecuteTemplate(w, identify, information)
if err != nil {
log.Println("template not discovered")
}
return err
}
func vetLogin(c echo.Context) error {
usr := c.FormValue("electronic mail")
pswd := c.FormValue("password")
rsltErr := accts.CompareUserCreds(usr, pswd)
if rsltErr != nil {
return echo.NewHTTPError(http.StatusUnauthorized, rsltErr)
}
tk, err := sessionmanager.CreateToken(usr, c)
if err != nil {
return echo.NewHTTPError(http.StatusBadRequest, err)
}
t, err := tk.SignedString([]byte(os.Getenv("HMAC_SECRET")))
if err != nil {
return err
}
expTime, expTimeErr := tk.Claims.GetExpirationTime()
if expTimeErr != nil {
return errors.New("error: didn't get expiration time")
}
ck := &http.Cookie{
Title: "Token",
Worth: t,
Quoted: false,
Expires: expTime.Time,
HttpOnly: true,
SameSite: http.SameSiteLaxMode,
}
c.SetCookie(ck)
// err = sessionmanager.AddToken(t, []byte(os.Getenv("HMAC_SECRET")), c)
if err != nil {
return echo.NewHTTPError(http.StatusBadRequest, err)
}
c.Request().AddCookie(ck)
return c.Render(http.StatusOK, "posts", "Add Posts to Your Feed")
}
func restricted(c echo.Context) error {
t, err := c.Cookie("Token")
if err != nil {
return c.HTML(http.StatusUnauthorized,
"No authorization token",
)
}
c.Request().Header.Set("Authorization:", "Bearer "+t.Worth)
claims, err := sessionmanager.GetUserCustomClaims(t.Worth, []byte(os.Getenv("HMAC_SECRET")))
// returns an http error on failure
if errors.Is(err, jwt.ErrTokenExpired) {
return errors.New("Token Expired")
}
if errors.Is(err, jwt.ErrSignatureInvalid) {
return errors.New("Token has an invalid signature")
}
if errors.Is(err, jwt.ErrTokenRequiredClaimMissing) {
return errors.New("Token is lacking required claims")
}
if errors.Is(err, jwt.ErrTokenSignatureInvalid) {
return errors.New("Token signature is invalid")
}
electronic mail := claims.Electronic mail
return c.Render(http.StatusOK, "pattern", "Welcome "+electronic mail+"!")
}
func primary() {
tm := &TemplateManager].tmpl")),
router := echo.New()
router.Use(middleware.SecureWithConfig(middleware.DefaultSecureConfig))
router.Use(middleware.Logger())
router.Use(middleware.Get well())
router.Renderer = tm
router.POST("/posts", vetLogin)
r := router.Group("/restricted")
// Configure middleware with the customized claims sort
config := echojwt.Config{
NewClaimsFunc: func(c echo.Context) jwt.Claims {
return new(sessionmanager.UserCustomClaims)
},
SigningKey: []byte(os.Getenv("HMAC_SECRET")),
}
r.Use(echojwt.WithConfig(config))
// Restricted group
r.GET("", restricted)
router.Logger.Deadly(router.Begin(":8080"))
}