JWT简介
很多时候,我们都可以利用 Session 的机制来实现登录功能。
除了 Session,另外一个可以考虑的选择就是使用 JWT。
JWT(JSON Web Token)是很常用的一种机制,主要用于身份认证,也就是登录。
它的基本原理就是通过加密生成一个 token,而后客户端每次访问的时候都带上这个 token。
它由三部分组成:
- Header:头部,JWT 的元数据,也就是描述这个 token 本身的数据,一个 JSON 对象。
- Payload:负载,数据内容,一个 JSON 对象。
- Signature:签名,根据 Header 和 Payload 生成。
注意,因为 Singnature 是根据 Header 和 Payload 来生成的,所以如果要是有人篡改了 Header 或者 Payload,那么 Signature 就会对不上。
Header 和 Payload 都是要被加密的。
使用JWT登录
我们只有两个接口,一个登录,一个获取用户信息,都很简单。接下来是普通登录代码。
func login(ctx *gin.Context) {
type Req struct {
Username string
Password string
}
var req Req
if err := ctx.Bind(&req); err != nil {
return
}
if req.Username == "username" && req.Password == "password" {
ctx.String(http.StatusOK, "登录成功")
return
}
ctx.String(http.StatusOK, "用户名或密码错误")
}
func profile(ctx *gin.Context) {
ctx.String(http.StatusOK, "profile")
}
//地址映射
server.POST("/users/login", login)
server.POST("/users/profile", profile)
server.Run(":8080")
首先我们要改造登录接口,也就是 login 方法。
因为使用 JWT 的核心,是要生成一个 JWT。
即,在登录成功后,生成一个 token 返回给前端。
这里我们直接使用go get github.com/golang-jwt/jwt/v5 来操作 JWT。
参考 JWT 的 API,很容易写出正确的代码。包括如下几个关键步骤:
- 定义 Claims:你可以理解为,你准备在 JWT 中存放的数据。
- 创建 Claims 并利用用户数据初始化好各个字段。
- 利用 JWT API 创建一个 JWT token。
- 将 token 加密为一个字符串。
- 将加密字符串放到 x-jwt-token 的头部,并返回前端。
// 步骤一:定义Claims
type UserClaims struct {
jwt.RegisteredClaims
// 假设在 JWT 中存放一个 Uid
Uid int64
}
if req.Username == "username" && req.Password == "password" {
var claims UserClaims
// 步骤二:初始化字段
claims.Uid = 12345
// 步骤三:创建一个 JTW token
token := jwt.NewWithClaims(jwt.SigningMethodRS256, claims)
// 步骤四:自定义一串字符串以生成 token
tokenStr, err := token.SignedString([]byte('XgZP9Ky1TqcfnlNp6cdsdsdamCgBkPrcXTUaM'))
if err != nil {
// 出错即为生成 token 的字符串失败
ctx.String(http.StatusOK, "Invalid")
}
// 步骤五:将 token 传给前端
ctx.Header("x-jwt-token", tokenStr)
ctx.String(http.StatusOK, "登录成功")
return
}
注意,后续前端需要把这个 token 再带回来,用户验证它已经登录。