这是我参与「第五届青训营 」伴学笔记创作活动的第 10 天
引入
JWT(json web token) token 是一种流行的权限验证,授权的标准(rfc7519)。
它定义了一种紧凑的、自包含的方式,用于在各方之间以JSON对象安全地传输信息。
相较于传统的token认证,在用户登录时服务端给前端返回token,并将token保存在服务端(Server)。 当用户访问时,需要携带token,服务端获取token后再去数据库获取token做校验,判断是否一致。
即 server_bakup_token <==> client_carried_token 做匹配
JWT的token认证,则是在用户登录时,服务端给用户返回一个token,但服务端不保存,以后用户再来访问时,需要携带token,服务端获取token做校验。
即不用将token保存在服务端(server端)
因为http是无状态的,所以需要在后端使用session,或者用jwt token替代。jwt token中包含用户信息,有效时间等,并用后端的密钥加密。
组成
分为三部分,分别是Header、payload、signature
失效
修改密码或退出登录时,需要把正在使用的token做失效处理,防止别的客户端访问
方案一:在每次修改密码或者退出登录后,修改一下自定义的盐值。
方案二:利用数据库,存放一个修改或者登出的时间,在创建token时,标注上创建时间。
使用体验
用户不仅要定义 authentication 验证逻辑
也要对保护路由定义 authorization 授权逻辑
对hertz-jwt
简单的生成逻辑如下
token, _, err := jwtAuthMiddleware.TokenGenerator(response.User.Id)
func (mw *HertzJWTMiddleware) TokenGenerator(data interface{}) (string, time.Time, error)
token := jwt.New(jwt.GetSigningMethod(mw.SigningAlgorithm))
claims := token.Claims.(jwt.MapClaims)
if mw.PayloadFunc != nil {
for key, value := range mw.PayloadFunc(data) {
claims[key] = value
}
}
expire := mw.TimeFunc().UTC().Add(mw.Timeout)
claims["exp"] = expire.Unix()
claims["orig_iat"] = mw.TimeFunc().Unix()
tokenString, err := mw.signedString(token)
if err != nil {
return "", time.Time{}, err
}
return tokenString, expire, nil
从 jwt token 中提取信息
claims := jwt.ExtractClaims(ctx, c)
userID := int64(claims[constants.IdentityKey].(float64))
reference:jwt的加密原理,和token的简单操作