欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Go語言中JWT的創(chuàng)建和解析操作詳解

 更新時(shí)間:2023年05月19日 08:57:20   作者:三杯溫開水  
JWT的全名是Json web token,是為了在網(wǎng)絡(luò)應(yīng)用環(huán)境間傳遞聲明而執(zhí)行的一種基于JSON的開放標(biāo)準(zhǔn),這篇文章主要介紹了在Go語言中JWT的創(chuàng)建和解析操作,感興趣的同學(xué)可以參考下文

JWT介紹

Json web token (JWT), 是為了在網(wǎng)絡(luò)應(yīng)用環(huán)境間傳遞聲明而執(zhí)行的一種基于JSON的開放標(biāo)準(zhǔn).該token被設(shè)計(jì)為緊湊且安全的,特別適用于分布式站點(diǎn)的單點(diǎn)登錄場景。JWT的聲明一般被用來在身份提供者和服務(wù)提供者間傳遞被認(rèn)證的用戶身份信息,以便于從資源服務(wù)器獲取資源,也可以增加一些額外的其它業(yè)務(wù)邏輯所必須的聲明信息,該token也可直接被用于認(rèn)證,也可被加密。下面就以一個(gè)標(biāo)準(zhǔn)的jwt功能實(shí)現(xiàn)方式進(jìn)行編碼。并且這個(gè)jwt也會(huì)相對安全一點(diǎn),因?yàn)槭怯屑用苓^的。一般用戶登錄后生成的token都是需要進(jìn)行加密的,每一次訪問,服務(wù)端都會(huì)根據(jù)前端的請求做出對應(yīng)的策略,避免一定的非必要腳本攻擊。

JWT相對于Cookie和Session的優(yōu)點(diǎn)

Cookie和Session存放在哪,相對于JWT有啥區(qū)別?

Cookie是儲(chǔ)存在客戶端的,Session是儲(chǔ)存在服務(wù)端的。

Cookie:

1、客戶端請求服務(wù)器后,如果服務(wù)器需要記錄用戶狀態(tài),服務(wù)器會(huì)在響應(yīng)信息中包含一個(gè)Set-Cookie的響應(yīng)頭

2、客戶端會(huì)根據(jù)這個(gè)響應(yīng)頭存儲(chǔ)Cookie信息。再次請求服務(wù)器時(shí),客戶端會(huì)在請求信息中包含一個(gè)Cookie請求頭。

Session:

反正就是服務(wù)端生成,存儲(chǔ)在服務(wù)器的內(nèi)存中以及保存在文件或數(shù)據(jù)庫中,返回給前端儲(chǔ)存到cookie中

1、session是有過期時(shí)間的,可以設(shè)置過期時(shí)間或者服務(wù)器關(guān)閉就會(huì)消失

2、session多了服務(wù)端會(huì)有內(nèi)存壓力,這就需要負(fù)載均衡了以及不同服務(wù)器的session共享問題。

JWT:

1、 在頭部信息中聲明加密算法和常量, 然后把header使用json轉(zhuǎn)化為字符串

2、在載荷中聲明用戶信息,同時(shí)還有一些其他的內(nèi)容;再次使用json 把載荷部分進(jìn)行轉(zhuǎn)化,轉(zhuǎn)化為字符串 (但是你覺得載荷中應(yīng)不應(yīng)該放置敏感的信息,當(dāng)然不行,因?yàn)橛行лd荷中的內(nèi)容是base64進(jìn)行編碼的,并不是進(jìn)行加密的,而且JWT存儲(chǔ)在localstorage等等,能夠被獲取到)

3、 使用在header中聲明的加密算法和每個(gè)項(xiàng)目隨機(jī)生成的secret來進(jìn)行加密, 把第一步分字符串和第二部分的字符串進(jìn)行加密, 生成新的字符串。此字符串是獨(dú)一無二的。

4、解密的時(shí)候,只要客戶端帶著JWT來發(fā)起請求,服務(wù)端就直接使用secret進(jìn)行解密。

你可以這樣理解,JWT不受瀏覽器之間的令牌約束,并且其是有加密的,可以一定程度上得到保護(hù)。

 第一部分為頭部(header),第二部分我們稱其為載荷(payload),第三部分是簽證(signature)。

實(shí)現(xiàn)jwt

引入jwt-go

我們需要先引入這個(gè)go-jwt

go get "github.com/dgrijalva/jwt-go"

創(chuàng)建一個(gè)jwt.go

jwt.StandardClaims 中有很多參數(shù),可以根據(jù)自己的需要進(jìn)行添加,可以查看源碼

// 設(shè)置token過期時(shí)間
const TokenExpireDuration = time.Hour * 2
var mySecret = []byte("努力學(xué)習(xí)go語言")
// 這里可以根據(jù)自己的業(yè)務(wù)做出更改
type MyClaims struct {
	UserID   int64  `json:"user_id"`
	UserName string `json:"user_name"`
	jwt.StandardClaims
}
// GenToken 生成JWT
func GenToken(userId int64, username string) (string, error) {
	// 創(chuàng)建我們自己聲明的數(shù)據(jù)
	c := MyClaims{
		userId,
		username, // 定義字段
		jwt.StandardClaims{
			IssuedAt: time.Now().Add(TokenExpireDuration).Unix(), // 過期時(shí)間
			Issuer:   "三杯溫開水",                                 // 簽發(fā)人
		},
	}
	// 使用指定的簽名方法創(chuàng)建簽名對象
	token := jwt.NewWithClaims(jwt.SigningMethodHS256, c)
	// 返回token
	return token.SignedString(mySecret)
}
// ParseToken 解析 JWT
func ParseToken(tokenString string) (*MyClaims, error) {
	mc := new(MyClaims)
	// 解析token
	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")
}

創(chuàng)建一個(gè)jwt的中間件

這個(gè)中間件一般會(huì)放置在需要用戶登錄情況下才可以進(jìn)行訪問的頁面或者數(shù)據(jù),比如:個(gè)人信息功能上。下面的是基于標(biāo)準(zhǔn)版的Authorization中,并使用Bearer開頭。可以根據(jù)自己的業(yè)務(wù)需求進(jìn)行做出更改

// JWTAuthMiddleware 基于JWT的認(rèn)證中間件
func JWTAuthMiddleware() func(c *gin.Context) {
	return func(c *gin.Context) {
		// 這里根據(jù)自己的業(yè)務(wù)進(jìn)行更改
		authHeader := c.Request.Header.Get("Authorization")
		if authHeader == "" {
			controller.ResponseError(c, controller.CodeNeedLogin)
			c.Abort()
			return
		}
		// 按空格分割(基于Bearer開頭的),如果不是Bearer開頭的下面代碼可以進(jìn)行省略
		// ------ start ------
		parts := strings.SplitN(authHeader, " ", 2)
		if !(len(parts) == 2 && parts[0] == "Bearer") {
			controller.ResponseError(c, controller.CodeInvalidToken)
			c.Abort()
			return
		}
		// ------ end -------
		// parts[1]是獲取到的tokenString,我們使用之前定義好的解析JWT的函數(shù)來解析它
		mc, err := jwt.ParseToken(parts[1])
		if err != nil {
			controller.ResponseError(c, controller.CodeInvalidToken)
			c.Abort()
			return
		}
		// 將當(dāng)前請求的username信息保存到請求的上下文c上
		c.Set(controller.CtxUserIdKey, mc.UserID)
		c.Next() // 后續(xù)的處理函數(shù)可以用過c.Get(CtxUserIdKey)來獲取當(dāng)前請求的用戶信息
	}
}

中間件引入到路由中

r.POST("/ping", JWTAuthMiddleware(), func(c *gin.Context) {
		c.String(http.StatusOK, "ok!")
	})

到此這篇關(guān)于Go語言中JWT的創(chuàng)建和解析操作詳解的文章就介紹到這了,更多相關(guān)Go JWT的創(chuàng)建和解析內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

最新評論