最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

golang中的jwt使用教程流程分析

 更新時(shí)間:2023年05月11日 14:37:32   作者:迷茫路人  
這篇文章主要介紹了golang中的jwt使用教程,接下來(lái)我們需要講解一下Claims該結(jié)構(gòu)體存儲(chǔ)了token字符串的超時(shí)時(shí)間等信息以及在解析時(shí)的Token校驗(yàn)工作,需要的朋友可以參考下

golang-jwt使用

老版本<v4.0.0 為github.com/dgrijalva/jwt-go 新版本https://github.com/golang-jwt/jwt

本文環(huán)境為新版本

加密

1.在使用之前我們應(yīng)該對(duì)它進(jìn)行安裝與導(dǎo)入

go get -u github.com/golang-jwt/jwt/v4
import "github.com/golang-jwt/jwt/v4"

2.既然導(dǎo)入成功那就開(kāi)始使用吧

package main
import (
   "fmt"
   "github.com/golang-jwt/jwt/v4"
)
func main() {
    // 創(chuàng)建秘鑰
   	key := []byte("aaa")
    // 創(chuàng)建Token結(jié)構(gòu)體
	claims := jwt.NewWithClaims(jwt.SigningMethodHS256, jwt.MapClaims{
		"user": "zhangshan",
		"pass": "123123",
	})
    // 調(diào)用加密方法,發(fā)揮Token字符串
	signingString, err := claims.SignedString(key)
	if err != nil {
		return
	}
	fmt.Println(signingString)
}
//這邊是輸出結(jié)果
&{ 0xc0000c2690 map[alg:ES256 typ:JWT] map[user:zhangshan]  false}
// 這是加密后的字符串
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJwYXNzIjoiMTIzMTIzIiwidXNlciI6InpoYW5nc2hhbiJ9.-2-xIJXMGKV-GyhM24OKbDVqWs4dsIANBsGhzXEfEFM

3.逐步講解

首先我們先查看第一步

claims := jwt.NewWithClaims(jwt.SigningMethodES256, jwt.MapClaims{
      "user": "zhangshan",
   })

newWithClaims會(huì)返回一個(gè)Token結(jié)構(gòu)體,而這個(gè)token結(jié)構(gòu)體有以下屬性

type Token struct {
   Raw       string        //原始令牌  
   Method    SigningMethod   // 加密方法 比如sha256加密      
   Header    map[string]interface{} // token頭信息
   Claims    Claims  // 加密配置,比如超時(shí)時(shí)間等             
   Signature string  // 加密后的字符串          
   Valid     bool   // 是否校驗(yàn)              
}
type Token struct {
   Raw       string        //原始令牌  
   Method    SigningMethod   // 加密方法 比如sha256加密      
   Header    map[string]interface{} // token頭信息
   Claims    Claims  // 加密配置,比如超時(shí)時(shí)間等             
   Signature string  // 加密后的字符串          
   Valid     bool   // 是否校驗(yàn)              
}

我們可以通過(guò)該結(jié)構(gòu)體獲取到加密后的字符串信息。

接下來(lái)我們需要講解一下Claims該結(jié)構(gòu)體存儲(chǔ)了token字符串的超時(shí)時(shí)間等信息以及在解析時(shí)的Token校驗(yàn)工作。

type Claims interface {
   Valid() error
}
//實(shí)現(xiàn)類(lèi)有MapClaims、RegisteredClaims、StandardClaims(舍棄)
//其實(shí)后兩個(gè)結(jié)構(gòu)體都是根據(jù)MapClaims編寫(xiě)而來(lái),所以我們只需要掌握MapClaims即可
type MapClaims map[string]interface{}

就是一個(gè)map集合,但是它實(shí)現(xiàn)了上面Valid()方法,該方法里面實(shí)現(xiàn)了對(duì)token過(guò)期日期校驗(yàn)、發(fā)布時(shí)間、生效時(shí)間的校驗(yàn)工作。
所以在map里面有三個(gè)固定的鍵我們可以根據(jù)需要進(jìn)行設(shè)置,exp 過(guò)期時(shí)間、iat 發(fā)布時(shí)間、nbf 生效時(shí)間

解密

既然已經(jīng)將Token值進(jìn)行了加密那么如何對(duì)其進(jìn)行驗(yàn)證(俗稱解密)那?

// 根據(jù)Token字符串解析成Claims結(jié)構(gòu)體
_, err = jwt.ParseWithClaims(signingString, jwt.MapClaims{}, func(token *jwt.Token) (interface{}, error) {
   fmt.Println(token.Header)
   return []byte("aaa"), nil
})
if err != nil {
   fmt.Println(err)
   return
}

在該方法中,有四個(gè)個(gè)參數(shù),我們需要注意第三個(gè)方法參數(shù),該類(lèi)型是一個(gè)方法,token作為參數(shù),兩個(gè)返回值,我們重點(diǎn)關(guān)注第一個(gè)返回值,該值會(huì)用來(lái)進(jìn)行編碼解析,所以我們需要傳入上文中的key秘鑰。

第四個(gè)參數(shù)為配置參數(shù),主要控制parse過(guò)程中對(duì)token的校驗(yàn)工作,比如調(diào)用WithoutClaimsValidation()則會(huì)關(guān)閉token的過(guò)期檢查等操作。

WithValidMethods(methods []string)  //指定使用的解密算法,他會(huì)跟token中加密方法進(jìn)行名稱比較,如果false則返回錯(cuò)誤值
WithoutClaimsValidation() // 忽略過(guò)期、發(fā)布時(shí)間等檢查

源碼分析

接下來(lái)我們將講解一下具體流程

SignedString

SignedString用來(lái)生成token結(jié)構(gòu)體

func (t *Token) SignedString(key interface{}) (string, error) {
   var sig, sstr string
   var err error
   // 通過(guò)base64 對(duì)header與claims進(jìn)行加密
   if sstr, err = t.SigningString(); err != nil {
      return "", err
   } 
   // 通過(guò)指定的加密方法,根據(jù)key值進(jìn)行加密
   if sig, err = t.Method.Sign(sstr, key); err != nil {
      return "", err
   }
   // 拼接token字符串
   return strings.Join([]string{sstr, sig}, "."), nil
}

ParseWithClaims

ParseWithClaims用來(lái)解析Token字符串返回token結(jié)構(gòu)體

func ParseWithClaims(tokenString string, claims Claims, keyFunc Keyfunc, options ...ParserOption) (*Token, error) {
   // 創(chuàng)建解析器,
   //ParseWithClaims 解析token字符串
   return NewParser(options...).ParseWithClaims(tokenString, claims, keyFunc)
}
func (p *Parser) ParseWithClaims(tokenString string, claims Claims, keyFunc Keyfunc) (*Token, error) {
    // 解析字符串,將根據(jù).進(jìn)行切割,通過(guò)base64進(jìn)行解碼,根據(jù)header中的alg屬性獲取加密方法比如sha256
    // 返回值token為T(mén)oken結(jié)構(gòu)體,parts為字符串切割后的數(shù)組
	token, parts, err := p.ParseUnverified(tokenString, claims)
	if err != nil {
		return token, err
	}
	// 判斷是否指定校驗(yàn)方法
	if p.ValidMethods != nil {
		var signingMethodValid = false
		var alg = token.Method.Alg()
		for _, m := range p.ValidMethods {
			if m == alg {
				signingMethodValid = true
				break
			}
		}
		if !signingMethodValid {
			// 指定方法與token中的方法不一致
			return token, NewValidationError(fmt.Sprintf("signing method %v is invalid", alg), ValidationErrorSignatureInvalid)
		}
	}
	// 獲取key秘鑰 
	var key interface{}
    // 判斷是否實(shí)現(xiàn)keyfunc,就是第三個(gè)參數(shù)
	if keyFunc == nil {
		// keyFunc was not provided.  short circuiting validation
		return token, NewValidationError("no Keyfunc was provided.", ValidationErrorUnverifiable)
	}
    // 調(diào)用方法,返回key值
	if key, err = keyFunc(token); err != nil {
		// keyFunc returned an error
		if ve, ok := err.(*ValidationError); ok {
			return token, ve
		}
		return token, &ValidationError{Inner: err, Errors: ValidationErrorUnverifiable}
	}
	vErr := &ValidationError{}
	// 判斷是否進(jìn)行校驗(yàn),SkipClaimsValidation默認(rèn)為false 加上!成為true
	if !p.SkipClaimsValidation {
		if err := token.Claims.Valid(); err != nil {
			// If the Claims Valid returned an error, check if it is a validation error,
			// If it was another error type, create a ValidationError with a generic ClaimsInvalid flag set
			if e, ok := err.(*ValidationError); !ok {
				vErr = &ValidationError{Inner: err, Errors: ValidationErrorClaimsInvalid}
			} else {
				vErr = e
			}
		}
	}
	// 進(jìn)行簽名驗(yàn)證
	token.Signature = parts[2]
	if err = token.Method.Verify(strings.Join(parts[0:2], "."), token.Signature, key); err != nil {
		vErr.Inner = err
		vErr.Errors |= ValidationErrorSignatureInvalid
	}
	if vErr.valid() {
		token.Valid = true
		return token, nil
	}
	return token, vErr
}

到此這篇關(guān)于golang中的jwt使用教程的文章就介紹到這了,更多相關(guān)golang jwt使用內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 詳解Golang中結(jié)構(gòu)體方法的高級(jí)應(yīng)用

    詳解Golang中結(jié)構(gòu)體方法的高級(jí)應(yīng)用

    本文旨在深度剖析Go中結(jié)構(gòu)體方法的高級(jí)應(yīng)用。我們不僅會(huì)回顧結(jié)構(gòu)體方法的基本概念和用法,還將探討如何通過(guò)高級(jí)技巧和最佳實(shí)踐,希望對(duì)大家有所幫助
    2024-01-01
  • Go語(yǔ)言題解LeetCode455分發(fā)餅干示例詳解

    Go語(yǔ)言題解LeetCode455分發(fā)餅干示例詳解

    這篇文章主要為大家介紹了Go語(yǔ)言題解LeetCode455分發(fā)餅干示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-12-12
  • Go語(yǔ)言常見(jiàn)錯(cuò)誤之誤用init函數(shù)實(shí)例解析

    Go語(yǔ)言常見(jiàn)錯(cuò)誤之誤用init函數(shù)實(shí)例解析

    Go語(yǔ)言中的init函數(shù)為開(kāi)發(fā)者提供了一種在程序正式運(yùn)行前初始化包級(jí)變量的機(jī)制,然而,由于init函數(shù)的特殊性,不當(dāng)?shù)厥褂盟赡芤鹨幌盗袉?wèn)題,本文將深入探討如何有效地使用init函數(shù),列舉常見(jiàn)誤用并提供相應(yīng)的避免策略
    2024-01-01
  • go語(yǔ)言time.After()的作用

    go語(yǔ)言time.After()的作用

    time.After 是 Go 語(yǔ)言中的一個(gè)函數(shù),用于返回一個(gè)定時(shí)器通道,該通道在指定時(shí)間后發(fā)送當(dāng)前時(shí)間,這個(gè)功能常用于超時(shí)控制和延遲執(zhí)行,本文就來(lái)詳細(xì)的介紹一下,感興趣的可以了解學(xué)習(xí)
    2024-10-10
  • golang的httpserver優(yōu)雅重啟方法詳解

    golang的httpserver優(yōu)雅重啟方法詳解

    這篇文章主要給大家介紹了關(guān)于golang的httpserver優(yōu)雅重啟的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧。
    2018-03-03
  • 使用Go?http重試請(qǐng)求的示例

    使用Go?http重試請(qǐng)求的示例

    開(kāi)發(fā)中對(duì)于http請(qǐng)求是經(jīng)常遇到,一般可能網(wǎng)絡(luò)延遲或接口返回超時(shí),這篇文章主要介紹了使用Go?http重試請(qǐng)求的示例,需要的朋友可以參考下
    2022-08-08
  • 使用gin框架搭建簡(jiǎn)易服務(wù)的實(shí)現(xiàn)方法

    使用gin框架搭建簡(jiǎn)易服務(wù)的實(shí)現(xiàn)方法

    go語(yǔ)言web框架挺多的,本文就介紹了一下如何使用gin框架搭建簡(jiǎn)易服務(wù)的實(shí)現(xiàn)方法,文中通過(guò)示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-12-12
  • golang 后臺(tái)進(jìn)程的啟動(dòng)和停止操作

    golang 后臺(tái)進(jìn)程的啟動(dòng)和停止操作

    這篇文章主要介紹了golang 后臺(tái)進(jìn)程的啟動(dòng)和停止操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2021-04-04
  • Go1.18新特性工作區(qū)模糊測(cè)試及泛型的使用詳解

    Go1.18新特性工作區(qū)模糊測(cè)試及泛型的使用詳解

    這篇文章主要為大家介紹了Go?1.18新特性中的工作區(qū)?模糊測(cè)試?泛型使用進(jìn)行詳細(xì)講解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-07-07
  • Golang 實(shí)現(xiàn)插入排序的方法示例(2種)

    Golang 實(shí)現(xiàn)插入排序的方法示例(2種)

    這篇文章主要介紹了Golang 實(shí)現(xiàn)插入排序的方法示例,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2020-02-02

最新評(píng)論

馆陶县| 文安县| 邵东县| 邢台市| 吉安市| 云龙县| 页游| 襄垣县| 阿拉善右旗| 西宁市| 林口县| 平和县| 大化| 百色市| 揭阳市| 固始县| 利辛县| 石嘴山市| 绩溪县| 松潘县| 古交市| 庆云县| 黄陵县| 永和县| 安丘市| 巩义市| 唐河县| 利津县| 梁山县| 郎溪县| 右玉县| 营山县| 天峻县| 丰城市| 哈尔滨市| 三明市| 安西县| 鄂州市| 阿拉善盟| 阿拉善盟| 广州市|