Gin(十二):整合 JWT

点击蓝色字关注我们!

一个努力中的公众号

长的好看的人都关注了

640?

在前后端分离的项目中,越来越多的项目采用JWT代替传统的cookie,这里我们来使用JWT结合Gin来作为一个登录授权和权限校验。

640

?什么是 JWT

640


JWT 的全称叫做 JSON WEB TOKEN,在目前前后端系统中使用较多。

JWT 构成

JWT 是由三段构成的。分别是 HEADER,PAYLOAD,VERIFY SIGNATURE,它们生成的信息通过.分割。

640?wx_fmt=jpeg

HEADER

header 是由 一个typalg组成,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 是否正确,如果正确则正确执行该请求,否者验证失败,重新登录。

640?wx_fmt=jpeg

640

?Gin 生成 JWT

640


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 = []byte(config.Secret)	
 tokenClaims := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)	
 // 省略代码

这里的config.OneDayOfHours设定了过期时间,这里设定了一天。通过StandardClaims 生成标准的载体,也就是上文提到的七个字段,其中 编号设定为 用户 id。其中的  jwtSecret是我们设定的密钥,

我们这里通过 HS256 算法生成tokenClaims,这就是我们的 HEADER 部分和 PAYLOAD。

 token, err := tokenClaims.SignedString(jwtSecret)

这样便生成了我们的 token 。我们要将我们的 token 和 Bearer 拼接在一起,同时中间用空格隔开。

 
 

生成 Bearer Token 。

当我们用户进行登录的时候,就可以通过该片段生成 JWT。

下面是完整代码:

 
 

通过 .http 请求测试,结果如下

 {	
   "result": {	
     "code": 200,	
     "message": "登录成功",	
     "data": "Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhdWQiOiIxMjMiLCJleHAiOjE1NjQ3OTY0MzksImp0aSI6Ilx1MDAwMCIsImlhdCI6MTU2NDc5NjQxOSwiaXNzIjoiZ2luIGhlbGxvIiwibmJmIjoxNTY0Nzk2NDE5LCJzdWIiOiJsb2dpbiJ9.CpacmfBSMgmK2TgrT-KwNB60bsvwgyryGQ0pWZr8laU"	
   }	
 }

这个便完成了token的生成。

640

?Gin 校验 Token

640


那么,接下来就需要完成 token 的验证。

还记得之前我们验证用户是否授权采用的办法吗?是的,在中间件里查看用户 cookie。同样的方法,我们这里校验用户 JWT 是否有效。

编写我们的中间件。

新建立middleware/Auth.go

首先先编写我们的解析 token 方法,parseToken()

func parseToken(token string) (*jwt.StandardClaims, error) {	
     jwtToken, err := jwt.ParseWithClaims(token, &jwt.StandardClaims{}, func(token *jwt.Token) (i interface{}, e error) {	
         return []byte(config.Secret), nil	
 })	
     if err == nil && jwtToken != nil {	
         if claim, ok := jwtToken.Claims.(*jwt.StandardClaims); ok && jwtToken.Valid {	
             return claim, nil	
         }	
 }	
     return nil, err	
 }

通过传入我们的 token , 来对 token 进行解析。

完整的中间件代码

 
 

首先在请求头获取 token ,然后对先把 token 进行解析,将 Bearer 和 JWT 拆分出来,将 JWT 进行校验。

我们只需要对我们需要校验的路由进行添加中间件校验即可。

 
 

当我们访问/的时候就需要携带 token 了

 GET http://localhost:8080	
 Content-Type: application/json	
 Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhdWQiOiIxMjMiLCJleHAiOjE1NjQ3OTQzNjIsImp0aSI6Ilx1MDAwMCIsImlhdCI6MTU2NDc5NDM0MiwiaXNzIjoiZ2luIGhlbGxvIiwibmJmIjoxNTY0Nzk0MzQyLCJzdWIiOiJsb2dpbiJ9.uQxGMsftyVFtYIGwQVm1QB2djw-uMfDbw81E5LMjliU


640

✍总结

640

本章节对什么是 JWT,Gin 中如何使用 JWT 做了介绍。但是不要过于迷信 JWT,JWT 还有很多问题,比如说 JWT 失效只能是时间过期,如果修改密码或者账户注销等操作需要我们另外添加逻辑判断。适合的地方选用适合的技术才能发挥最大的优势。

640

?‍?本章节代码

640


Github 请点击 阅读原文

往期推荐

Gin(一):Hello Gin

Gin(二):路由Router

Gin(三):配合模板 Tmpl

Gin(四):表单数据提交和模型绑定

Gin(五):连接MySQL

Gin(六):文件的上传

Gin(七):中间件的使用和定义

Gin(八): Cookie 的使用

Gin(九):生成 restful 接口

Gin(十):集成 Swagger 生成 API 文档

Gin(十一):集成 gorm

640?wx_fmt=jpeg

好看的人才能点

640

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值