Go Fiber框架中如何访问JWT Claims内的email字段值
报错原因
你使用token.Claims.Email访问字段报错,是因为jwt.MapClaims的底层类型是map[string]interface{},并非定义了Email属性的结构体,自然不支持点语法直接访问字段。
另外你当前代码直接丢弃了jwt.ParseWithClaims返回的错误,没有校验token合法性,存在严重安全隐患,伪造、过期、签名不合法的token都会导致后续逻辑崩溃。
解决方案
解析成功后,jwt.MapClaims类型的claims变量已经存储了所有JWT载荷内容,直接通过键名索引取值,配合类型断言即可拿到email字段,完整修正代码如下:
import ( "fmt" "github.com/gofiber/fiber/v2" "github.com/golang-jwt/jwt/v5" ) func User(c *fiber.Ctx) error { cookie := c.Cookies("jwt") claims := jwt.MapClaims{} token, err := jwt.ParseWithClaims(cookie, claims, func(token *jwt.Token) (interface{}, error) { // 校验签名算法,避免算法替换攻击 if _, ok := token.Method.(*jwt.SigningMethodHMAC); !ok { return nil, fmt.Errorf("invalid signing method: %v", token.Header["alg"]) } return []byte(SecretKey), nil }) // 校验token有效性 if err != nil || !token.Valid { return c.Status(fiber.StatusUnauthorized).JSON(fiber.Map{ "msg": "身份凭证无效", }) } // 取email字段,做类型断言 email, ok := claims["email"].(string) if !ok { return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{ "msg": "凭证中缺少邮箱字段", }) } // 此处可直接使用email变量做用户身份校验 return c.JSON(fiber.Map{ "email": email, }) }
可选:结构体方式(支持点语法访问)
如果你习惯用点语法访问字段,可以自定义Claims结构体替换jwt.MapClaims,解析完成后即可直接通过属性访问:
// 自定义声明结构体 type MyClaims struct { Email string `json:"email"` jwt.RegisteredClaims // 内嵌JWT标准声明 } func User(c *fiber.Ctx) error { cookie := c.Cookies("jwt") // 初始化自定义声明实例 claims := &MyClaims{} token, err := jwt.ParseWithClaims(cookie, claims, func(token *jwt.Token) (interface{}, error) { if _, ok := token.Method.(*jwt.SigningMethodHMAC); !ok { return nil, fmt.Errorf("invalid signing method: %v", token.Header["alg"]) } return []byte(SecretKey), nil }) if err != nil || !token.Valid { return c.Status(fiber.StatusUnauthorized).JSON(fiber.Map{"msg": "身份凭证无效"}) } // 直接点语法访问email email := claims.Email return c.JSON(fiber.Map{"email": email}) }
内容的提问来源于stack exchange,提问作者Haresh Akalanka
相关产品推荐
相关产品推荐

