go-micro微服務(wù)JWT跨域認(rèn)證問(wèn)題
一 JWT介紹
JWT 英文名是 Json Web Token ,是一種用于通信雙方之間傳遞安全信息的簡(jiǎn)潔的、URL安全的表述性聲明規(guī)范,經(jīng)常用在跨域身份驗(yàn)證。
JWT 以 JSON 對(duì)象的形式安全傳遞信息。因?yàn)榇嬖跀?shù)字簽名,因此所傳遞的信息是安全的。
一個(gè)JWT Token就像這樣:
eyJhbGci0iJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyX2lkIjoyODAx0DcyNzQ40DMyMzU4NSwiZ
XhwIjoxNTk0NTQwMjkxLCJpc3MiOiJibHV1YmVsbCJ9.1k_ZrAtYGCeZhK3iupHxP1kgjBJzQTVTtX0iZYFx9wU
它是由.分隔的三部分組成,這三部分依次是:
- 頭部(Header)
- 負(fù)載(Payload)
- 簽名(Signature)
頭部和負(fù)載以jSON形式存在,這就是JWT中的JSON,三部分的內(nèi)容都分別單獨(dú)經(jīng)過(guò)了Base64編
碼,以.拼接成一個(gè)JWT Token。
二 JWT優(yōu)缺點(diǎn)
JWT擁有基于Token的會(huì)話(huà)管理方式所擁有的一切優(yōu)勢(shì),不依賴(lài)Cookie,使得其可以防止CSRF攻
擊,也能在禁用Cookie的瀏覽器環(huán)境中正常運(yùn)行。
而JWT的最大優(yōu)勢(shì)是服務(wù)端不再需要存儲(chǔ)Session,使得服務(wù)端認(rèn)證鑒權(quán)業(yè)務(wù)可以方便擴(kuò)展,避免存儲(chǔ)
Session所需要引入的Redis等組件,降低了系統(tǒng)架構(gòu)復(fù)雜度。但這也是JWT最大的劣勢(shì),由于有效期
存儲(chǔ)在Token中,JWT Token一旦簽發(fā),就會(huì)在有效期內(nèi)一直可用,無(wú)法在服務(wù)端廢止,當(dāng)用戶(hù)進(jìn)行登
出操作,只能依賴(lài)客戶(hù)端刪除掉本地存儲(chǔ)的JWT Token,如果需要禁用用戶(hù),單純使用JWT就無(wú)法做到。
三 JWT使用
1. 導(dǎo)包和數(shù)據(jù)定義
package token import ( "account/config/redis" "errors" "fmt" "github.com/dgrijalva/jwt-go" "time" ) // MyClaims 自定義聲明結(jié)構(gòu)體并內(nèi)嵌jwt.StandardClaims // jwt包自帶的jwt.StandardClaims只包含了官方字段 // 我們這里需要額外記錄一個(gè)username字段,所以要自定義結(jié)構(gòu)體 // 如果想要保存更多信息,都可以添加到這個(gè)結(jié)構(gòu)體中 type MyClaims struct { UserName string `json:"username"` jwt.StandardClaims } const TokenExpireDuration = time.Hour * 2 var MySecret = []byte("Account")
2.生成JWT
// GenToken 生成JWT func GenToken(UserName string) (string, error) { // 創(chuàng)建一個(gè)我們自己的聲明 c := MyClaims{ UserName, // 自定義字段 jwt.StandardClaims{ ExpiresAt: time.Now().Add(TokenExpireDuration).Unix(), // 過(guò)期時(shí)間 Issuer: "Account", // 簽發(fā)人 }, } // 使用指定的簽名方法創(chuàng)建簽名對(duì)象 token := jwt.NewWithClaims(jwt.SigningMethodHS256, c) // 使用指定的secret簽名并獲得完整的編碼后的字符串token return token.SignedString(MySecret) }
3.解析JWT
// ParseToken 解析JWT func ParseToken(tokenString string) (*MyClaims, error) { // 解析token var mc = new(MyClaims) token, err := jwt.ParseWithClaims(tokenString, mc, func(token *jwt.Token) (i interface{}, err error) { return MySecret, nil }) if err != nil { return nil, err } if token.Valid { // 校驗(yàn)token return mc, nil } return nil, errors.New("invalid token") }
4.完整代碼
package token import ( "account/config/redis" "errors" "fmt" "github.com/dgrijalva/jwt-go" "time" ) // MyClaims 自定義聲明結(jié)構(gòu)體并內(nèi)嵌jwt.StandardClaims // jwt包自帶的jwt.StandardClaims只包含了官方字段 // 我們這里需要額外記錄一個(gè)username字段,所以要自定義結(jié)構(gòu)體 // 如果想要保存更多信息,都可以添加到這個(gè)結(jié)構(gòu)體中 type MyClaims struct { UserName string `json:"username"` jwt.StandardClaims } const TokenExpireDuration = time.Hour * 2 var MySecret = []byte("Account") // GenToken 生成JWT func GenToken(UserName string) (string, error) { // 創(chuàng)建一個(gè)我們自己的聲明 c := MyClaims{ UserName, // 自定義字段 jwt.StandardClaims{ ExpiresAt: time.Now().Add(TokenExpireDuration).Unix(), // 過(guò)期時(shí)間 Issuer: "Account", // 簽發(fā)人 }, } // 使用指定的簽名方法創(chuàng)建簽名對(duì)象 token := jwt.NewWithClaims(jwt.SigningMethodHS256, c) // 使用指定的secret簽名并獲得完整的編碼后的字符串token return token.SignedString(MySecret) } // ParseToken 解析JWT func ParseToken(tokenString string) (*MyClaims, error) { // 解析token var mc = new(MyClaims) token, err := jwt.ParseWithClaims(tokenString, mc, func(token *jwt.Token) (i interface{}, err error) { return MySecret, nil }) if err != nil { return nil, err } if token.Valid { // 校驗(yàn)token return mc, nil } return nil, errors.New("invalid token") }
四 最后
至此,go-micro微服務(wù)JWT跨域認(rèn)證工作就正式完成。
接下來(lái)就開(kāi)始公用函數(shù)的代碼編寫(xiě)了,希望大家關(guān)注博主和關(guān)注專(zhuān)欄,第一時(shí)間獲取最新內(nèi)容,每篇博客都干貨滿(mǎn)滿(mǎn)。
到此這篇關(guān)于go-micro微服務(wù)JWT跨域認(rèn)證的文章就介紹到這了,更多相關(guān)go-micro微服務(wù)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
golang常用庫(kù)之配置文件解析庫(kù)-viper使用詳解
viper 配置管理解析庫(kù),是由大神 Steve Francia 開(kāi)發(fā),他在google領(lǐng)導(dǎo)著 golang 的產(chǎn)品開(kāi)發(fā),他也是 gohugo.io 的創(chuàng)始人之一,命令行解析庫(kù) cobra 開(kāi)發(fā)者,這篇文章主要介紹了golang常用庫(kù)之配置文件解析庫(kù)-viper使用詳解,需要的朋友可以參考下2020-10-10Go語(yǔ)言學(xué)習(xí)之JSON編碼解析與使用
這篇文章主要為大家詳細(xì)介紹了Go語(yǔ)言中JSON編碼的解析與使用已經(jīng)JSON與Map、結(jié)構(gòu)體的互相轉(zhuǎn)化,文中的示例代碼講解詳細(xì),需要的可以參考一下2023-02-02Go語(yǔ)言常見(jiàn)錯(cuò)誤之a(chǎn)ny沒(méi)傳遞任何信息解決分析
Go語(yǔ)言,由于其高效強(qiáng)大的并行處理能力和優(yōu)雅簡(jiǎn)單的設(shè)計(jì)哲學(xué),一直以來(lái)都是編程世界的寵兒,然而,對(duì)于一些Go新手和甚至熟悉Go的程序員也可能會(huì)遇到一個(gè)常見(jiàn)的錯(cuò)誤:?any沒(méi)傳遞任何信息,那么,如何規(guī)避這個(gè)錯(cuò)誤,本文將揭示其中的秘密2024-01-01GO實(shí)現(xiàn)基于命令行的簡(jiǎn)單IPS程序代碼
本文介紹了入侵防御系統(tǒng)IPS的工作原理和實(shí)現(xiàn),IPS通過(guò)網(wǎng)絡(luò)流量監(jiān)控和實(shí)時(shí)響應(yīng),防止網(wǎng)絡(luò)攻擊,通過(guò)使用Go語(yǔ)言實(shí)現(xiàn)一個(gè)簡(jiǎn)單的IPS示例程序,展示了如何獲取本地IP地址和探測(cè)網(wǎng)絡(luò)中其他設(shè)備的IP地址,包括如何定義和加載規(guī)則文件,以及如何檢測(cè)IP對(duì)相應(yīng)端口的訪(fǎng)問(wèn)是否達(dá)到規(guī)定閾值2024-12-12Go語(yǔ)言解決大模型API調(diào)用中的超時(shí)錯(cuò)誤的方法
在開(kāi)發(fā)基于大語(yǔ)言模型(如DeepSeek)的智能應(yīng)用時(shí),我們常通過(guò)API實(shí)現(xiàn)自然語(yǔ)言交互,但在處理復(fù)雜任務(wù)或網(wǎng)絡(luò)波動(dòng)時(shí),開(kāi)發(fā)者可能會(huì)遭遇 context deadline exceeded錯(cuò)誤,本文將以Go語(yǔ)言為例,深入分析該問(wèn)題的根源,并提供一套完整的優(yōu)化方案,需要的朋友可以參考下2025-05-05Go語(yǔ)言實(shí)現(xiàn)管理多個(gè)數(shù)據(jù)庫(kù)連接
在軟件開(kāi)發(fā)過(guò)程中,使用?MySQL、PostgreSQL?或其他數(shù)據(jù)庫(kù)是很常見(jiàn)的,由于配置和要求不同,管理這些連接可能具有挑戰(zhàn)性,下面就來(lái)和大家聊聊如何在Go中管理多個(gè)數(shù)據(jù)庫(kù)連接吧2023-10-10