在前后端分离的项目中,越来越多的项目采用 JWT
代替传统的 cookie
,这里我们来使用 JWT
结合 Gin
来作为一个登录授权和权限校验。
?什么是 JWT
JWT 的全称叫做 JSON WEB TOKEN,在目前前后端系统中使用较多。
JWT 构成
JWT 是由三段构成的。分别是 HEADER,PAYLOAD,VERIFY SIGNATURE,它们生成的信息通过 .
分割。
HEADER
header 是由 一个 typ
和 alg
组成,typ
会指明为 JWT,而 alg
是所使用的加密算法。
{
"alg": "HS256",
"typ": "JWT"
}
PAYLOAD
payload 是 JWT 的载体,也就是我们要承载的信息。这段信息是我们可以自定义的,可以定义我们要存放什么信息,那些字段。该部分信息不宜过多,它会影响 JWT 生成的大小,还有就是请勿将敏感数据存入该部分,该端数据前端是可以解析获取 token 内信息的。
官方给了七个默认字段,我们可以不全部使用,也可以加入我们需要的字段。
名称 | 含义 |
---|---|
Audience | 表示JWT的受众 |
ExpiresAt | 失效时间 |
Id | 签发编号 |
IssuedAt | 签发时间 |
Issuer | 签发人 |
NotBefore | 生效时间 |
Subject | 主题 |
VERIFY SIGNATURE
这也是 JWT 的最后一段,该部分是由算法计算完成的。
对刚刚的 header 进行 base64Url 编码,对 payload 进行 base64Url 编码,两端完成编码后通过 .
进行连接起来。
base64UrlEncode(header).base64UrlEncode(payload)
完成上述步骤后,就要通过我们 header 里指定的加密算法对上部分进行加密,同时我们还要插入我们的一个密钥,来确保我的 JWT 签发是安全的。
这便是我们的第三部分。
当三部分都完成后,通过使用 .
将三部分分割,生成了上图所示的 JWT 。
JWT 登录原理
简单的说就是当用户登录的时候,服务器校验登录名称和密码是否正确,正确的话,会生成 JWT 返回给客户端。客户端获取到 JWT 后要进行保存,之后的每次请求都会讲 JWT 携带在头部,每次服务器都会获取头部的 JWT 是否正确,如果正确则正确执行该请求,否者验证失败,重新登录。
?Gin 生成 JWT
go 语言的 JWT 库有很多。jwt.io 上也给出了很多 。这里使用 jwt-go
"github.com/dgrijalva/jwt-go"
我们对登录方法进行改造。
// 省略代码
expiresTime := time.Now().Unix() + int64(config.OneDayOfHours)
claims := jwt.StandardClaims{
Audience: user.Username, // 受众
ExpiresAt: expiresTime, // 失效时间
Id: string(user.ID), // 编号
IssuedAt: time.Now().Unix(), // 签发时间
Issuer: "gin hello", // 签发人
NotBefore: time.Now().Unix(), // 生效时间
Subject: "login", // 主题
}
var jwtSecret