这是我参与「第三届青训营 -后端场」笔记创作活动的第3篇笔记
接上篇:JWT详解(中) | 青训营笔记 - 掘金 (juejin.cn)
3. 在go中使用JWT
3.1 使用JWT进行用户身份认证的流程
- 此处只做最简单的演示,仅演示如何使用JWT
- 客户端将user_id发送给服务器
- 服务器通过自己的密钥将user_id进行加密,生产token
- 服务器将加密后的token返回给客户端,客户端保存token
- 客户端下次请求时,将本地的token一起发送给服务器
- 服务器通过自己的密钥将token解密,比对user_id和token过期时间,若不通过则要求客户端重新登录
首次请求:
下一次请求:
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 生成步骤:
- 根据需求定义自己的结构体
- 使用指定的签名方法创建签名对象
- 使用指定的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
}