我有以下功能使用 v2 版本使用 gofiber 框架创建服务器端 HTTPOnly"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",
})
}
这是它在登录时返回的内容
{
"access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhY2Nlc3NfdXVpZCI6ImFlMmQ4MDlhLTNhZDgtNDgwNS1iMjZlLWUyYWMwNTYyMjZhZiIsImF1dGhvcml6ZWQiOnRydWUsImV4cCI6MTY0MTE4NTg5MCwicGVybWlzc2lvbiI6InVzZXIiLCJzdWIiOiJ0ZXN0OEBleGFtcGxlLmNvbSJ9.cXzkNoDb1XKmt_quQ4ONvDcXfmPrBjt4umG38a1xwqA",
"refresh_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJyZWZyZXNoX3V1aWQiOiJhZTJkODA5YS0zYWQ4LTQ4MDUtYjI2ZS1lMmFjMDU2MjI2YWYrK3Rlc3Q4QGV4YW1wbGUuY29tIn0._6zOG65GmnwbWnpKaQb2LxuPIhKZGCzg9P62xoBds8U",
"token_type": "bearer"
}
cookieaccess_token
是使用 的值创建的eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhY2Nlc3NfdXVpZCI6ImFlMmQ4MDlhLTNhZDgtNDgwNS1iMjZlLWUyYWMwNTYyMjZhZiIsImF1dGhvcml6ZWQiOnRydWUsImV4cCI6MTY0MTE4NTg5MCwicGVybWlzc2lvbiI6InVzZXIiLCJzdWIiOiJ0ZXN0OEBleGFtcGxlLmNvbSJ9.cXzkNoDb1XKmt_quQ4ONvDcXfmPrBjt4umG38a1xwqA
,如果检查 cookie 的有效负载数据,则会得到以下
{
"access_uuid": "ae2d809a-3ad8-4805-b26e-e2ac056226af",
"authorized": true,
"exp": 1641185890,
"permission": "user",
"sub": "test8@example.com"
}
所以现在我想要另一个函数来拉取并能够在 cookie 中获取所有这些有效负载数据,以便我可以在应用程序中使用它
这是我拥有的一个功能,它应该获取这些数据,但事情不正常,而且 gofiber 没有记录任何错误,因此很难进行故障排除
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
}
我在这里做错了什么? ad
应该能够返回完整的有效负载数据,就像从这样的登录函数创建的数据
{
"access_uuid": "ae2d809a-3ad8-4805-b26e-e2ac056226af",
"authorized": true,
"exp": 1641185890,
"permission": "user",
"sub": "test8@example.com"
}
这样我就可以从中获取我需要的任何数据