Go Web校验JWT需同时解析签名并验证exp/iat等声明,须用jwt.ParseWithClaims传入具体claims结构体和匹配密钥的回调函数,中间件要规范提取Bearer Token并透传claims。
Go Web接口校验JWT合法性,核心就两件事:解析签名 + 验证声明(尤其是和),缺一不可。
只验签名不查过期,等于给过期令牌开绿灯;只查时间不验签名,攻击者随便改个
就能越权。
用
解析并校验签名和标准声明
这是最常出错的一步——很多人直接用
,它默认不校验
/
,导致过期 token 仍被接受。
必须传入具体 claims 结构体(如自定义
或
),不能只传空指针
密钥
回调函数
必须返回
,且类型要匹配签名算法(如
对应 HMAC)
错误类型要细分处理:
的
字段可位与判断是过期、未生效还是签名错误
中间件中提取
并透传用户信息
常见坑是没统一处理 header 格式,或忽略大小写、空格、前缀缺失等边界情况。
返回值可能带空格,要用
前缀判断必须用
,不能硬切
(否则遇到
或
就 panic)
校验通过后,用
存入
,但注意:value 类型要一致,建议封装成导出常量 key,避免字符串拼错
自定义 claims 结构体必须嵌入
(v5 推荐)
v4 中用
,v5 已弃用,改用
。不嵌入会导致
/
等字段无法被自动校验。
go语言参考手册 中文CHM版
Go 是一个开源的编程语言,它能让构造简单、可靠且高效的软件变得容易。本文给大家带来Go参考手册,需要的可以来下载! Go是从2007年末由Robert Griesemer, Rob Pike, Ken Thompson主持开发,后来还加入了Ian Lance Taylor, Russ Cox等人,并最终于2009年11月开源,在2012年早些时候发布了Go 1稳定版本。现在Go的开发已经是完全开放的,并且拥有一个活跃的社区。 Go 语言特色 简洁、快速、安全 并行、有趣、开源 内存管理、v数组安全、编译
下载
立即学习
“
go语言免费学习笔记(深入)
”;
结构体字段名必须小写 +
tag,否则
转换会丢数据
自定义字段(如
)要加
tag,否则解析后为空
别在 claims 里存敏感信息(如密码、手机号),JWT 是 Base64Url
编码
,不是加密
真正难的不是写对这几行代码,而是上线后面对并发刷新 token、时钟不同步、密钥轮换这些场景——比如
时间戳依赖服务器本地时间,若 NTP 同步失败,整个鉴权链就不可信。这些细节,往往比语法更决定系统是否真的安全。
expiatuser_idjwt.ParseWithClaimsjwt.ParseexpiatCustomClaimsjwt.MapClaims[]byteSigningMethodHS256*jwt.ValidationErrorErrorsfunc ParseToken(tokenStr string) (*CustomClaims, error) {
claims := &CustomClaims{}
token, err := jwt.ParseWithClaims(tokenStr, claims, func(t *jwt.Token) (interface{}, error) {
if _, ok := t.Method.(*jwt.SigningMethodHMAC); !ok {
return nil, fmt.Errorf("unexpected signing method")
}
return jwtKey, nil
})
if err != nil {
if ve, ok := err.(*jwt.ValidationError); ok {
switch {
case ve.Errors&jwt.ValidationErrorExpired != 0:
return nil, errors.New("token expired")
case ve.Errors&jwt.ValidationErrorNotValidYet != 0:
return nil, errors.New("token not active yet")
default:
return nil, errors.New("invalid token signature")
}
}
return nil, err
}
if !token.Valid {
return nil, errors.New("token invalid")
}
return claims, nil
}Authorization: Bearer xxxr.Header.Get("Authorization")strings.TrimSpacestrings.HasPrefix(auth, "Bearer ")[7:]"bearer xxx""Bearerxxx"context.WithValueclaimsjwt.RegisteredClaimsjwt.StandardClaimsjwt.RegisteredClaimsexpiatjsonMapClaimsUserIDjsontype CustomClaims struct {
UserID uint `json:"user_id"`
Role string `json:"role"`
jwt.RegisteredClaims
}exp