文章目录
一:介绍
- JWT现在比较流行的认证方式,微服务中使用特别常见。
- JWT标准格式
在HTTP请求添加名为Authorization的header,形式如下: (token前面
Bearer
是标准前缀字符串)
Authorization: Bearer
- Go JWT 结构体
Claims
,可以理解为需要保存的信息,加密后会存储在token
中,解密后会从token自动解析出来
配合
ant design pro
前端实现需要解决以下问题:
JWT TOKEN
需要存储哪些字段以及定义,如何创建和解析- 前端发送请求时如何自动添加
JWT
认证信息 JWT TOKEN
过期后,前后端如何配合自动刷新
二:Gin JWT 后台
使用库
github.com/golang-jwt/jwt/v5
1. Claims
定义
jwt.RegisteredClaims
是github.com/golang-jwt/jwt/v5
预设的标准claims
,后面用到其ExpiresAt
过期时间字段,UserClaims
为自定义存储的字段,最终加密到token中的是jwtClaims
结构
type UserClaims struct {
// 可以添加字段存储其他信息
UserID uint `json:"userId"`
RoleID uint `json:"roleId"`
UserName string `json:"username"`
}
type jwtClaims struct {
UserClaims
jwt.RegisteredClaims
}
2. 创建和解析Token
expireHours
和refreshHours
分别是设置过期时间,以及距离过期时间多久返回新token,后续在gin中间件中判断,方式是在Header
中返回x-refresh-token
:newToken
type JWT struct {
secret []byte
expireHours time.Time
refreshHours time.Duration
}
// j := NewJWT("密钥", 2, 1)
// token过期时间是2小时, 距离过期时间还有1小时时在`Header`中返回`x-refresh-token`:`newToken`
func NewJWT(secret string, expireHours int, refreshHours int) *JWT {
return &JWT{
secret: []byte(secret),
expireHours: time.Now().Add(time.Duration(expireHours) * time.Hour),
refreshHours: time.Hour * time.Duration(refreshHours),
}
}
func (j *JWT) CreateToken(u UserClaims) (string, error) {
token := jwt.NewWithClaims(jwt.SigningMethodHS256, jwtClaims{
UserClaims: u,
RegisteredClaims: jwt.RegisteredClaims{
ExpiresAt: jwt.NewNumericDate(j.expireHours),
IssuedAt: jwt.NewNumericDate(time.Now()),
},
})
return token.SignedString(j.secret)
}
func (j *JWT) ParseToken(tokenString string) (*jwtClaims, error) {
token, err := jwt.ParseWithClaims(tokenString, &jwtClaims{
}, func(token *jwt.Token) (interface{
}, error) {
return j.secret, nil
})
if err != nil {
return nil, err
}
if claims, ok := token.Claims.(*jwtClaims); ok && token.Valid {
return claims, nil
} else {
return nil, errors.New("Token无效")
}
}
文章评论