JWT详解(下) | 青训营笔记

128 阅读2分钟

这是我参与「第三届青训营 -后端场」笔记创作活动的第3篇笔记

接上篇:JWT详解(中) | 青训营笔记 - 掘金 (juejin.cn)

3. 在go中使用JWT

3.1 使用JWT进行用户身份认证的流程

  1. 此处只做最简单的演示,仅演示如何使用JWT
  2. 客户端将user_id发送给服务器
  3. 服务器通过自己的密钥将user_id进行加密,生产token
  4. 服务器将加密后的token返回给客户端,客户端保存token
  5. 客户端下次请求时,将本地的token一起发送给服务器
  6. 服务器通过自己的密钥将token解密,比对user_id和token过期时间,若不通过则要求客户端重新登录

首次请求:

image.png

下一次请求: image.png

3.2 导入JWT包

go get github.com/golang-jwt/jwt

3.3 加密

3.3.1

首先需要生成我们自己特定信息,可以自定义结构体,加入自己想要的信息和一些预定义的声明。其中 jwt.StandardClaims 是官方字段

   type MapClaims struct{
      "user_id": user_id,
      "exp":     time.Now().Unix() + 5,
   }

其中:

  • "exp":指明了令牌过期时间的
  • "user_id":是我们自定义的属性 接着定义一个我们自己的密钥:
var mySigningKey = []byte("qwacdfafaefa.")  

生成JWT 生成步骤:

  1. 根据需求定义自己的结构体
  2. 使用指定的签名方法创建签名对象
  3. 使用指定的secret签名并获得完整的编码后的字符串token
//加密token
func TokenEncrypt(user_id string) string {

    //使用指定的签名方法创建签名对象
   token := jwt.NewWithClaims(jwt.SigningMethodHS256, jwt.MapClaims{
      "user_id": user_id,
      "exp":     time.Now().Unix() + 5,
   })

    //使用指定的secret签名并获得完整的编码后的字符串token
   tokenString, err := token.SignedString(mySigningKey)
   if err != nil {
      log.Println(err.Error())
      return tokenString
   } else {
      return tokenString
   }
}

3.3 解密

//解密token
func TokenParse(tokenString string) interface{} {
   token, err := jwt.Parse(tokenString, func(t *jwt.Token) (interface{}, error) {
      if _, ok := t.Method.(*jwt.SigningMethodHMAC); !ok {
         return nil, fmt.Errorf("Unexpected signing method: %v", t.Header["alg"])
      }
      return mySigningKey, nil
   })

   user_id := token.Claims.(jwt.MapClaims)["user_id"]

   if err != nil {
      log.Println(err.Error())
      return user_id
   }
   return user_id
}