加入收藏 | 设为首页 | 会员中心 | 我要投稿 河北网 (https://www.hebeiwang.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 建站 > 正文

Golang不到100行实现一套灵活的JWT库

发布时间:2019-10-20 12:14:26 所属栏目:建站 来源:Golang全栈
导读:【大咖·来了 第7期】10月24日晚8点寓目《智能导购对话呆板人实践》 JWT 全 chen JSON Web Tokens 此刻被普及的应用于各类前后端疏散的场景,他比传统的 Token Session 方法,更具机动性。 虽然网上也有许多开源的 JWT 库,很是之多,开源组织也提供了官方
副问题[/!--empirenews.page--] 【大咖·来了 第7期】10月24日晚8点寓目《智能导购对话呆板人实践》

JWT 全 chen JSON Web Tokens 此刻被普及的应用于各类前后端疏散的场景,他比传统的 Token Session 方法,更具机动性。

虽然网上也有许多开源的 JWT 库,很是之多,开源组织也提供了官方的库。

Golang不到100行实现一套机动的JWT库

可以会见这网址去下载:

  • https://jwt.io

可是假如我们知其然而不知其以是然的行使,不免会有许多题目。

以是这次分享下,我最近本身写的一个 JWT 库,代码已经上传到 github 上了,地点如下:

  • https://github.com/liu578101804/go-tool/tree/master/jwt

对比着名的 JWT 库来说,我没有任何上风,只是作为进修行使,接待各人指正个中的不敷。

下面就给各人说下我的实现思绪吧。

JWT 的道理

我们要实现 JWT 算法就得先相识他的道理,我只管用剪短的话去表明:

JWT 算法输出的数据是一串包括 header(头信息).payload(内容).signature(署名) 的一段字符串。

来一段真实的 JWT 天生的字符串:

  1. eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c 

是不是豁然爽朗了,这串字符串又叫 token ,由于这串 token 内里包括了验证必要的信息,对比传统的 session 必要随处事器内里去取验证的信息,越发的机动独立。

由于他不依靠 session 这种传统的存储,别用在漫衍式处事器内里有着很大的上风。

虽然他也有弱点,最头痛就这 2 点:

  • 不行控。一旦签发出去的 token 将无法提前让他烧毁,不像传统的,我可以把我 session 内里的 token 删了下次过来,token 就失效了。虽然这也不是没步伐办理,在整个别系内里插手黑名单机制就行,只是轻微贫困了点。
  • 信息相对传统的 session 数据量和隐私性没那么好。由于 token 一样平常都不提议出格长,以是 payload 承载的数据量是有限的。同时字符串内里的 payload 是可以被解密的,以是存在必然性的被破译风险(虽然你可以行使较量难破译的算法去低落这个风险)。

算法构成

JWT 的算法构成很简朴,只必要 一个可逆的加密算法去加密 header(头信息).payload(内容),一个不行逆的算法去对前面这部门内容举办加密署名天生 signature(署名) 就行。

假如我们用差异的加密算法组合便形成了差异的 JWT 加密算法。好比:

  • HS256 (HMAC + SHA-256)
  • RS256 (RSA + SHA-256)

虽然尚有许多,你可以本身去组合,我们将写的这个库支持你自界说。

详细实现

下面就开始进入代码实现阶段了:

说下我的计划思绪,Golang 他有一个自然的上风就是支持把函数作为变量传入,我们便可以按照这一特征把加密部门让挪用者去实现,我们把实现主体就行,这样便我们的 JWT 便很是机动了。

我们要写的主体代码去掉注释空行不到 100 行。

jwt.go

  1. package jwt 
  2.  
  3. import ( 
  4.     "encoding/json" 
  5.     "strings" 
  6.     "fmt" 
  7.  
  8. //声明一个尺度的JWT接口 
  9. type IJwt interface { 
  10.     //配置头部 
  11.     SetHeader(string) 
  12.     //配置署名算法 
  13.     SetSignFunc(SignFunc) 
  14.     //配置编码算法 
  15.     SetEncodeFunc(EncodeFunc) 
  16.  
  17.     //写入body 
  18.     WriteBody(map[string]interface{}) 
  19.  
  20.     //天生jwt 
  21.     CreateJwtString() (string,error) 
  22.     //验证jwt 
  23.     CheckJwtString(string) bool 
  24.  
  25. //类型header的名目 
  26. type Header struct { 
  27.     Type    string  `json:"type"` 
  28.     Alg     string  `json:"alg"` 
  29.  
  30. //署名算法 
  31. type SignFunc func([]byte) string 
  32. //编码算法 
  33. type EncodeFunc func([]byte) string 
  34.  
  35.  
  36. //声明一个布局图 去实现 尺度的JWT接口 
  37. type Jwt struct { 
  38.     Header      Header 
  39.     Body        map[string]interface{} 
  40.  
  41.     signFun     SignFunc 
  42.     encodeFun   EncodeFunc 
  43.  
  44. //配置头部信息,声名你行使的署名算法 
  45. func (j *Jwt) SetHeader(headerType string){ 
  46.     j.Header =  Header{ 
  47.         Type: "JWT", 
  48.         Alg: headerType, 
  49.     } 
  50.  
  51. //配置署名算法 
  52. func (j *Jwt) SetSignFunc(signFunc SignFunc) { 
  53.     j.signFun = signFunc 
  54.  
  55. //配置对 header 和 body 的加密算法 
  56. func (j *Jwt) SetEncodeFunc(encodeFunc EncodeFunc) { 
  57.     j.encodeFun = encodeFunc 
  58.  
  59. //写入要加密的内容 
  60. func (j *Jwt) WriteBody(body map[string]interface{}) { 
  61.     j.Body = body 
  62.  
  63. //天生token 
  64. func (j *Jwt) CreateJwtString() (string,error) { 
  65.     //编码header 
  66.     headerByte,err := json.Marshal(j.Header) 
  67.     if err != nil { 
  68.         return "",err 
  69.     } 
  70.     headerStr := j.encodeFun(headerByte) 
  71.  
  72.     //编码body 
  73.     bodyByte,err := json.Marshal(j.Body) 
  74.     if err != nil { 
  75.         return "",err 
  76.     } 
  77.     bodyStr := j.encodeFun(bodyByte) 
  78.  
  79.     //署名 
  80.     signByte := j.signFun([]byte(string(headerStr)+"."+string(bodyStr))) 
  81.  
  82.     return fmt.Sprintf("%s.%s.%s",headerStr,bodyStr,signByte),nil 
  83.  
  84. //验证 token 是否合规 
  85. func (j *Jwt) CheckJwtString(input string) bool  { 
  86.     arr := strings.Split(input,".") 
  87.     //名目是否正确 
  88.     if len(arr) != 3 { 
  89.         return false 
  90.     } 
  91.     //署名 
  92.     signByte := j.signFun([]byte(string(arr[0])+"."+string(arr[1]))) 
  93.     if string(signByte) != arr[2] { 
  94.         return false 
  95.     } 
  96.     return true 

这个文件就已经把 JWT 的焦点给写好了,此刻只必要按照你想要的加密算法举办添补就好了。

(编辑:河北网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

热点阅读