跳转到主内容
新派编程网 - 新潮编程理念,全新技术课堂!

Golang Web接口如何校验JWT合法性_鉴权校验方式说明

Go Web校验JWT需同时解析签名并验证exp/iat等声明,须用jwt.ParseWithClaims传入具体claims结构体和匹配密钥的回调函数,中间件要规范提取Bearer Token并透传claims。 Go Web接口校验JWT合法性,核心就两件事:解析签名 + 验证声明(尤其是
exp
和
iat
),缺一不可。 只验签名不查过期,等于给过期令牌开绿灯;只查时间不验签名,攻击者随便改个
user_id
就能越权。 用
jwt.ParseWithClaims
解析并校验签名和标准声明 这是最常出错的一步——很多人直接用
jwt.Parse
,它默认不校验
exp
/
iat
,导致过期 token 仍被接受。 必须传入具体 claims 结构体(如自定义
CustomClaims
或
jwt.MapClaims
),不能只传空指针 密钥 回调函数 必须返回
[]byte
,且类型要匹配签名算法(如
SigningMethodHS256
对应 HMAC) 错误类型要细分处理:
*jwt.ValidationError
的
Errors
字段可位与判断是过期、未生效还是签名错误
func 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 xxx
并透传用户信息 常见坑是没统一处理 header 格式,或忽略大小写、空格、前缀缺失等边界情况。
r.Header.Get("Authorization")
返回值可能带空格,要用
strings.TrimSpace
前缀判断必须用
strings.HasPrefix(auth, "Bearer ")
,不能硬切
[7:]
(否则遇到
"bearer xxx"
或
"Bearerxxx"
就 panic) 校验通过后,用
context.WithValue
存入
claims
,但注意:value 类型要一致,建议封装成导出常量 key,避免字符串拼错 自定义 claims 结构体必须嵌入
jwt.RegisteredClaims
(v5 推荐) v4 中用
jwt.StandardClaims
,v5 已弃用,改用
jwt.RegisteredClaims
。不嵌入会导致
exp
/
iat
等字段无法被自动校验。 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语言免费学习笔记(深入) ”; 结构体字段名必须小写 +
json
tag,否则
MapClaims
转换会丢数据 自定义字段(如
UserID
)要加
json
tag,否则解析后为空 别在 claims 里存敏感信息(如密码、手机号),JWT 是 Base64Url 编码 ,不是加密
type CustomClaims struct { UserID uint `json:"user_id"` Role string `json:"role"` jwt.RegisteredClaims }
真正难的不是写对这几行代码,而是上线后面对并发刷新 token、时钟不同步、密钥轮换这些场景——比如
exp
时间戳依赖服务器本地时间,若 NTP 同步失败,整个鉴权链就不可信。这些细节,往往比语法更决定系统是否真的安全。

相关文章