| 
                        副标题[/!--empirenews.page--]
                        【大咖·来了 第7期】10月24日晚8点观看《智能导购对话机器人实践》
             JWT 全 chen JSON Web Tokens 现在被广泛的应用于各种前后端分离的场景,他比传统的 Token Session  方式,更具灵活性。 
当然网上也有很多开源的 JWT 库,非常之多,开源组织也提供了官方的库。 
  
可以访问这网址去下载: 
但是如果我们知其然而不知其所以然的使用,难免会有很多问题。 
所以这次分享下,我最近自己写的一个 JWT 库,代码已经上传到 github 上了,地址如下: 
    - https://github.com/liu578101804/go-tool/tree/master/jwt
 
 
相比出名的 JWT 库来说,我没有任何优势,只是作为学习使用,欢迎大家指正其中的不足。 
下面就给大家说下我的实现思路吧。 
JWT 的原理 
我们要实现 JWT 算法就得先了解他的原理,我尽量用剪短的话去解释: 
JWT 算法输出的数据是一串包含 header(头信息).payload(内容).signature(签名) 的一段字符串。 
来一段真实的 JWT 生成的字符串: 
- 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 
- package jwt 
 -  
 - import ( 
 -     "encoding/json" 
 -     "strings" 
 -     "fmt" 
 - ) 
 -  
 - //声明一个标准的JWT接口 
 - type IJwt interface { 
 -     //设置头部 
 -     SetHeader(string) 
 -     //设置签名算法 
 -     SetSignFunc(SignFunc) 
 -     //设置编码算法 
 -     SetEncodeFunc(EncodeFunc) 
 -  
 -     //写入body 
 -     WriteBody(map[string]interface{}) 
 -  
 -     //生成jwt 
 -     CreateJwtString() (string,error) 
 -     //验证jwt 
 -     CheckJwtString(string) bool 
 - } 
 -  
 - //规范header的格式 
 - type Header struct { 
 -     Type    string  `json:"type"` 
 -     Alg     string  `json:"alg"` 
 - } 
 -  
 - //签名算法 
 - type SignFunc func([]byte) string 
 - //编码算法 
 - type EncodeFunc func([]byte) string 
 -  
 -  
 - //声明一个结构图 去实现 标准的JWT接口 
 - type Jwt struct { 
 -     Header      Header 
 -     Body        map[string]interface{} 
 -  
 -     signFun     SignFunc 
 -     encodeFun   EncodeFunc 
 - } 
 -  
 - //设置头部信息,说明你使用的签名算法 
 - func (j *Jwt) SetHeader(headerType string){ 
 -     j.Header =  Header{ 
 -         Type: "JWT", 
 -         Alg: headerType, 
 -     } 
 - } 
 -  
 - //设置签名算法 
 - func (j *Jwt) SetSignFunc(signFunc SignFunc) { 
 -     j.signFun = signFunc 
 - } 
 -  
 - //设置对 header 和 body 的加密算法 
 - func (j *Jwt) SetEncodeFunc(encodeFunc EncodeFunc) { 
 -     j.encodeFun = encodeFunc 
 - } 
 -  
 - //写入要加密的内容 
 - func (j *Jwt) WriteBody(body map[string]interface{}) { 
 -     j.Body = body 
 - } 
 -  
 - //生成token 
 - func (j *Jwt) CreateJwtString() (string,error) { 
 -     //编码header 
 -     headerByte,err := json.Marshal(j.Header) 
 -     if err != nil { 
 -         return "",err 
 -     } 
 -     headerStr := j.encodeFun(headerByte) 
 -  
 -     //编码body 
 -     bodyByte,err := json.Marshal(j.Body) 
 -     if err != nil { 
 -         return "",err 
 -     } 
 -     bodyStr := j.encodeFun(bodyByte) 
 -  
 -     //签名 
 -     signByte := j.signFun([]byte(string(headerStr)+"."+string(bodyStr))) 
 -  
 -     return fmt.Sprintf("%s.%s.%s",headerStr,bodyStr,signByte),nil 
 - } 
 -  
 - //验证 token 是否合规 
 - func (j *Jwt) CheckJwtString(input string) bool  { 
 -     arr := strings.Split(input,".") 
 -     //格式是否正确 
 -     if len(arr) != 3 { 
 -         return false 
 -     } 
 -     //签名 
 -     signByte := j.signFun([]byte(string(arr[0])+"."+string(arr[1]))) 
 -     if string(signByte) != arr[2] { 
 -         return false 
 -     } 
 -     return true 
 - } 
 
  
这个文件就已经把 JWT 的核心给写好了,现在只需要根据你想要的加密算法进行填充就好了。 
                                                (编辑:52站长网) 
【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! 
                     |