JWT Token 学习 | 青训营笔记

83 阅读2分钟

这是我参与「第五届青训营 」伴学笔记创作活动的第 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的简单操作