How do i grab the jwt payload data from a cookie created with gofiber golang framework?

huangapple go评论72阅读模式
英文:

How do i grab the jwt payload data from a cookie created with gofiber golang framework?

问题

你好!根据你提供的代码,我看到你想要编写一个函数来提取cookie中的payload数据。根据你的描述,你的函数似乎没有返回预期的结果。以下是可能导致问题的几个地方:

  1. 请确保在函数中正确引用jwt包。你的代码中没有显示导入该包,所以请确保你已经正确导入了jwt包。

  2. 请检查jwt.ParseWithClaims函数的返回值。如果解析失败,该函数将返回一个错误。你可以在函数中添加一些日志输出,以便查看是否有错误发生。

  3. 确保AccessDetailsClaims结构体中的字段标签与cookie中的字段名称匹配。在你的代码中,字段标签中的json标签似乎有一些问题。请确保字段标签中的名称与cookie中的字段名称完全匹配。

请检查以上几点,并尝试进行调试。如果问题仍然存在,请提供更多关于问题的详细信息,以便我可以更好地帮助你解决问题。

英文:

I have the following function to create a server side HTTPOnly with gofiber framework using the v2 version "github.com/gofiber/fiber/v2"

func Signin(c *fiber.Ctx) error {
	
	type SigninData struct {
		Email  string `json:"email" xml:"email" form:"email"`
		Password string `json:"password" xml:"password" form:"password"`
	}

	data := SigninData{}

	if err := c.BodyParser(&data); err != nil {
		return err
	}

	var user models.User

	findUser := database.DB.Where("email = ?", data.Email).First(&user)

	if findUser == nil {
		c.Status(fiber.StatusBadRequest)
		return c.JSON(fiber.Map{
			"message": "Account not found",
		})
	}

	if err := user.ComparePassword(data.Password); err != nil {
		c.Status(fiber.StatusBadRequest)
		return c.JSON(fiber.Map{
			"message": "Invalid credentials",
		})
	}

	isSuperuser := database.DB.Where("email = ? AND is_superuser = ?", data.Email, true).First(&user).Error

	var scope string

	if errors.Is(isSuperuser, gorm.ErrRecordNotFound) {
		scope = "user"
	} else {
		scope = "admin"
	}

	token, err := middlewares.CreateTokens(user.Email, scope)

	if err != nil {
		c.Status(fiber.StatusBadRequest)
		return c.JSON(fiber.Map{
			"message": "Could not generate session tokens",
		})	
	}

	saveErr := middlewares.RedisStoreTokens(user.Email, token)
	if saveErr != nil {
		c.Status(fiber.StatusBadRequest)
		return c.JSON(fiber.Map{
			"message": "Could not save session to redis",
		})
	}
	tokens := map[string]string{
		"access_token":  token.AccessToken,
		"refresh_token": token.RefreshToken,
	}

	cookie := fiber.Cookie{
		Name: "access_token",
		Value: tokens["access_token"],
		Expires: time.Now().Add(time.Hour * 24),
		HTTPOnly: true,
		Secure:   true,
	}

	c.Cookie(&cookie)

	return c.JSON(fiber.Map{
		"access_token": tokens["access_token"],
		"refresh_token": tokens["refresh_token"],
		"token_type": "bearer",
	})

}

Here is what it returned on signin

{
    "access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhY2Nlc3NfdXVpZCI6ImFlMmQ4MDlhLTNhZDgtNDgwNS1iMjZlLWUyYWMwNTYyMjZhZiIsImF1dGhvcml6ZWQiOnRydWUsImV4cCI6MTY0MTE4NTg5MCwicGVybWlzc2lvbiI6InVzZXIiLCJzdWIiOiJ0ZXN0OEBleGFtcGxlLmNvbSJ9.cXzkNoDb1XKmt_quQ4ONvDcXfmPrBjt4umG38a1xwqA",
    "refresh_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJyZWZyZXNoX3V1aWQiOiJhZTJkODA5YS0zYWQ4LTQ4MDUtYjI2ZS1lMmFjMDU2MjI2YWYrK3Rlc3Q4QGV4YW1wbGUuY29tIn0._6zOG65GmnwbWnpKaQb2LxuPIhKZGCzg9P62xoBds8U",
    "token_type": "bearer"
}

cookie access_token is created with the value of eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhY2Nlc3NfdXVpZCI6ImFlMmQ4MDlhLTNhZDgtNDgwNS1iMjZlLWUyYWMwNTYyMjZhZiIsImF1dGhvcml6ZWQiOnRydWUsImV4cCI6MTY0MTE4NTg5MCwicGVybWlzc2lvbiI6InVzZXIiLCJzdWIiOiJ0ZXN0OEBleGFtcGxlLmNvbSJ9.cXzkNoDb1XKmt_quQ4ONvDcXfmPrBjt4umG38a1xwqA
and if one checks the payload data of the cookie one gets the following

{
  "access_uuid": "ae2d809a-3ad8-4805-b26e-e2ac056226af",
  "authorized": true,
  "exp": 1641185890,
  "permission": "user",
  "sub": "test8@example.com"
}

So now i want another function that will pull and be able to grab all of these payload data within the cookie so i can use it within the app

Here is a function i have that is supposed to grab those data but things are not working and gofiber does not log any error so difficult to even troubleshoot

type ClaimsWithScope struct {
	jwt.RegisteredClaims
	Scope string `json:"permissions"`
}
type AccessDetails struct {
	AccessUuid   string  `json:"access_uuid"`
	Email        string  `json:"email"`
}
type AccessDetailsClaims struct {
	jwt.RegisteredClaims
	Scope        string  `json:"permissions"`
	AccessUuid   string  `json:"access_uuid"`
	Authorized   string  `json:"authorized"`
}
...
...
...
func GetAccessDetails(c *fiber.Ctx) (*AccessDetails, error) {
	ad := &AccessDetails{}

	cookie := c.Cookies("access_token")

	var err error
	token, err := jwt.ParseWithClaims(cookie, &AccessDetailsClaims{}, func(token *jwt.Token) (interface{}, error) {
		return []byte(SecretKey), nil
	})

	if err != nil {
		return nil, err
	}

	payload := token.Claims.(*AccessDetailsClaims)

	ad.Email = payload.Subject
	ad.AccessUuid = payload.AccessUuid

	return ad, nil
}

what am i doing wrong here? ad should be able to return the full payload data like those created from the signin function like this

{
  "access_uuid": "ae2d809a-3ad8-4805-b26e-e2ac056226af",
  "authorized": true,
  "exp": 1641185890,
  "permission": "user",
  "sub": "test8@example.com"
}

so i can then be able to grab whatever data i need from it

答案1

得分: 3

最终找到了解决方法:

func GetAccessDetails(c *fiber.Ctx) (*AccessDetails, error) {
	ad := &AccessDetails{}

	cookie := c.Cookies("access_token")

	var err error
	token, err := jwt.Parse(cookie, func(token *jwt.Token) (interface{}, error) {
		return []byte(os.Getenv("ACCESS_SECRET")), nil
	})

	if err != nil {
		return nil, err
	}

	payload := token.Claims.(jwt.MapClaims)

	ad.Email = payload["sub"].(string)
	ad.AccessUuid = payload["access_uuid"].(string)

	return ad, nil
}

因此,由于我使用了mapClaims来创建令牌,所以我可以使用以下代码来获取它:

token, err := jwt.Parse(cookie, func(token *jwt.Token) (interface{}, error) {
		return []byte(os.Getenv("ACCESS_SECRET")), nil
	})

然后将ad := &AccessDetails{}的元素分配如下:

payload := token.Claims.(jwt.MapClaims)

ad.Email = payload["sub"].(string)
ad.AccessUuid = payload["access_uuid"].(string)
英文:

finally figured it out

func GetAccessDetails(c *fiber.Ctx) (*AccessDetails, error) {
	ad := &AccessDetails{}

	cookie := c.Cookies("access_token")

	var err error
	token, err := jwt.Parse(cookie, func(token *jwt.Token) (interface{}, error) {
		return []byte(os.Getenv("ACCESS_SECRET")), nil
	})

	if err != nil {
		return nil, err
	}

	payload := token.Claims.(jwt.MapClaims)

	ad.Email = payload["sub"].(string)
	ad.AccessUuid = payload["access_uuid"].(string)

	return ad, nil
}

so since i used mapClaims to create the token, so i can grab it with this

token, err := jwt.Parse(cookie, func(token *jwt.Token) (interface{}, error) {
		return []byte(os.Getenv("ACCESS_SECRET")), nil
	})

and then assigns the elements of ad := &AccessDetails{} as follows

	payload := token.Claims.(jwt.MapClaims)

	ad.Email = payload["sub"].(string)
	ad.AccessUuid = payload["access_uuid"].(string)

huangapple
  • 本文由 发表于 2022年1月3日 12:49:43
  • 转载请务必保留本文链接:https://go.coder-hub.com/70561778.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定