英文:
How do i grab the jwt payload data from a cookie created with gofiber golang framework?
问题
你好!根据你提供的代码,我看到你想要编写一个函数来提取cookie中的payload数据。根据你的描述,你的函数似乎没有返回预期的结果。以下是可能导致问题的几个地方:
-
请确保在函数中正确引用
jwt
包。你的代码中没有显示导入该包,所以请确保你已经正确导入了jwt
包。 -
请检查
jwt.ParseWithClaims
函数的返回值。如果解析失败,该函数将返回一个错误。你可以在函数中添加一些日志输出,以便查看是否有错误发生。 -
确保
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)
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论