如何用Golang實現(xiàn)一套靈活的JWT庫,很多新手對此不是很清楚,為了幫助大家解決這個難題,下面小編將為大家詳細講解,有這方面需求的人可以來學(xué)習(xí)下,希望你能有所收獲。
成都創(chuàng)新互聯(lián)公司專注于任縣企業(yè)網(wǎng)站建設(shè),響應(yīng)式網(wǎng)站,商城開發(fā)。任縣網(wǎng)站建設(shè)公司,為任縣等地區(qū)提供建站服務(wù)。全流程定制設(shè)計,專業(yè)設(shè)計,全程項目跟蹤,成都創(chuàng)新互聯(lián)公司專業(yè)和態(tài)度為您提供的服務(wù)
JWT 全 chen JSON Web Tokens 現(xiàn)在被廣泛的應(yīng)用于各種前后端分離的場景,他比傳統(tǒng)的 Token Session 方式,更具靈活性。
當(dāng)然網(wǎng)上也有很多開源的 JWT 庫,非常之多,開源組織也提供了官方的庫。
我最近自己寫的一個 JWT 庫,代碼已經(jīng)上傳到 github 上了,地址如下:
https://github.com/liu578101804/go-tool/tree/master/jwt
相比出名的 JWT 庫來說,我沒有任何優(yōu)勢,只是作為學(xué)習(xí)使用,歡迎大家指正其中的不足。
下面就給大家說下我的實現(xiàn)思路吧。
JWT 的原理
我們要實現(xiàn) JWT 算法就得先了解他的原理,我盡量用剪短的話去解釋:
JWT 算法輸出的數(shù)據(jù)是一串包含 header(頭信息).payload(內(nèi)容).signature(簽名) 的一段字符串。
來一段真實的 JWT 生成的字符串:
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
是不是豁然開朗了,這串字符串又叫 token ,因為這串 token 里面包含了驗證需要的信息,相比傳統(tǒng)的 session 需要到服務(wù)器里面去取驗證的信息,更加的靈活獨立。
因為他不依賴 session 這種傳統(tǒng)的存儲,別用在分布式服務(wù)器里面有著很大的優(yōu)勢。
當(dāng)然他也有缺點,最頭痛就這 2 點:
不可控。一旦簽發(fā)出去的 token 將無法提前讓他銷毀,不像傳統(tǒng)的,我可以把我 session 里面的 token 刪了下次過來,token 就失效了。當(dāng)然這也不是沒辦法解決,在整個體系里面加入黑名單機制就行,只是稍微麻煩了點。
信息相對傳統(tǒng)的 session 數(shù)據(jù)量和隱私性沒那么好。因為 token 一般都不建議特別長,所以 payload 承載的數(shù)據(jù)量是有限的。同時字符串里面的 payload 是可以被解密的,所以存在一定性的被破譯風(fēng)險(當(dāng)然你可以使用比較難破譯的算法去降低這個風(fēng)險)。
算法組成
JWT 的算法組成很簡單,只需要 一個可逆的加密算法去加密 header(頭信息).payload(內(nèi)容),一個不可逆的算法去對前面這部分內(nèi)容進行加密簽名生成 signature(簽名) 就行。
如果我們用不同的加密算法組合便形成了不同的 JWT 加密算法。比如:
HS256 (HMAC + SHA-256)
RS256 (RSA + SHA-256)
當(dāng)然還有很多,你可以自己去組合,我們將寫的這個庫支持你自定義。
具體實現(xiàn)
下面就開始進入代碼實現(xiàn)階段了:
說下我的設(shè)計思路,Golang 他有一個天然的優(yōu)勢就是支持把函數(shù)作為變量傳入,我們便可以根據(jù)這一特性把加密部分讓調(diào)用者去實現(xiàn),我們把實現(xiàn)主體就行,這樣便我們的 JWT 便非常靈活了。
我們要寫的主體代碼去掉注釋空行不到 100 行。
jwt.go
package jwt import ( "encoding/json" "strings" "fmt" ) //聲明一個標(biāo)準(zhǔn)的JWT接口 type IJwt interface { //設(shè)置頭部 SetHeader(string) //設(shè)置簽名算法 SetSignFunc(SignFunc) //設(shè)置編碼算法 SetEncodeFunc(EncodeFunc) //寫入body WriteBody(map[string]interface{}) //生成jwt CreateJwtString() (string,error) //驗證jwt CheckJwtString(string) bool } //規(guī)范header的格式 type Header struct { Type string `json:"type"` Alg string `json:"alg"` } //簽名算法 type SignFunc func([]byte) string //編碼算法 type EncodeFunc func([]byte) string //聲明一個結(jié)構(gòu)圖 去實現(xiàn) 標(biāo)準(zhǔn)的JWT接口 type Jwt struct { Header Header Body map[string]interface{} signFun SignFunc encodeFun EncodeFunc } //設(shè)置頭部信息,說明你使用的簽名算法 func (j *Jwt) SetHeader(headerType string){ j.Header = Header{ Type: "JWT", Alg: headerType, } } //設(shè)置簽名算法 func (j *Jwt) SetSignFunc(signFunc SignFunc) { j.signFun = signFunc } //設(shè)置對 header 和 body 的加密算法 func (j *Jwt) SetEncodeFunc(encodeFunc EncodeFunc) { j.encodeFun = encodeFunc } //寫入要加密的內(nèi)容 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 是否合規(guī) 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 }
這個文件就已經(jīng)把 JWT 的核心給寫好了,現(xiàn)在只需要根據(jù)你想要的加密算法進行填充就好了。
下面我們就去實現(xiàn)一個最簡單的 RS256 算法,新建一個 bs.go 文件,內(nèi)容如下:
package jwt import ( "crypto/sha256" "encoding/base64" "fmt" ) func NewRS256() IJwt { jwtM := Jwt{} //Sha256 jwtM.SetSignFunc(func(bytes []byte) string { h := sha256.New() h.Write(bytes) return fmt.Sprintf("%x",h.Sum(nil)) }) //base64 jwtM.SetEncodeFunc(func(bytes []byte) string { return base64.URLEncoding.EncodeToString(bytes) }) return &jwtM }
我這里 header 和 payload 采用 base64 去加密,簽名采用 sha256 當(dāng)然這種算法生成的 JWT 很容易被人串改模仿,不能用于生產(chǎn)的。
看完上述內(nèi)容是否對您有幫助呢?如果還想對相關(guān)知識有進一步的了解或閱讀更多相關(guān)文章,請關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道,感謝您對創(chuàng)新互聯(lián)的支持。
網(wǎng)站題目:如何用Golang實現(xiàn)一套靈活的JWT庫
本文鏈接:http://vcdvsql.cn/article12/jhiigc.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供動態(tài)網(wǎng)站、企業(yè)網(wǎng)站制作、網(wǎng)站建設(shè)、外貿(mào)建站、網(wǎng)站營銷、微信公眾號
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)