亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

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

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

golang-jwt使用

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

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

加密

1.在使用之前我們應該對它進行安裝與導入

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

2.既然導入成功那就開始使用吧

package main
import (
   "fmt"
   "github.com/golang-jwt/jwt/v4"
)
func main() {
    // 創(chuàng)建秘鑰
   	key := []byte("aaa")
    // 創(chuàng)建Token結構體
	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)
}
//這邊是輸出結果
&{ 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會返回一個Token結構體,而這個token結構體有以下屬性

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

我們可以通過該結構體獲取到加密后的字符串信息。

接下來我們需要講解一下Claims該結構體存儲了token字符串的超時時間等信息以及在解析時的Token校驗工作。

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

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

解密

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

// 根據(jù)Token字符串解析成Claims結構體
_, 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
}

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

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

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

源碼分析

接下來我們將講解一下具體流程

SignedString

SignedString用來生成token結構體

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

ParseWithClaims

ParseWithClaims用來解析Token字符串返回token結構體

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ù).進行切割,通過base64進行解碼,根據(jù)header中的alg屬性獲取加密方法比如sha256
    // 返回值token為Token結構體,parts為字符串切割后的數(shù)組
	token, parts, err := p.ParseUnverified(tokenString, claims)
	if err != nil {
		return token, err
	}
	// 判斷是否指定校驗方法
	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{}
    // 判斷是否實現(xiàn)keyfunc,就是第三個參數(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{}
	// 判斷是否進行校驗,SkipClaimsValidation默認為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
			}
		}
	}
	// 進行簽名驗證
	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
}

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

相關文章

  • golang 使用time包獲取時間戳與日期格式化操作

    golang 使用time包獲取時間戳與日期格式化操作

    這篇文章主要介紹了golang 使用time包獲取時間戳與日期格式化操作,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-12-12
  • golang中兩個協(xié)程交替打印數(shù)字和字母的實現(xiàn)

    golang中兩個協(xié)程交替打印數(shù)字和字母的實現(xiàn)

    這篇文章給大家介紹了golang中兩個協(xié)程交替打印數(shù)字和字母的實現(xiàn),文中通過代碼示例講解的非常詳細,對大家的學習或工作有一定的幫助,需要的朋友可以參考下
    2024-01-01
  • golang panic及處理機制

    golang panic及處理機制

    Go語言追求簡潔優(yōu)雅,所以,Go語言不支持傳統(tǒng)的 try…catch…finally 這種異常,因為Go語言的設計者們認為,將異常與控制結構混在一起會很容易使得代碼變得混亂,今天給大家介紹golang panic及處理機制,需要的朋友參考下吧
    2021-08-08
  • 詳解如何在Go語言中循環(huán)數(shù)據(jù)結構

    詳解如何在Go語言中循環(huán)數(shù)據(jù)結構

    這篇文章主要為大家詳細介紹了如何在Go語言中循環(huán)數(shù)據(jù)結構(循環(huán)字符串、循環(huán)map結構和循環(huán)Struct),文中的示例代碼代碼講解詳細,需要的可以參考一下
    2022-10-10
  • 一起聊聊Go語言中的語法糖的使用

    一起聊聊Go語言中的語法糖的使用

    語法糖通常是用來簡化代碼編寫的,特性就是使用語法糖前后編譯的結果是相同的。這篇文章主要就來和大家一起聊聊Go語言中的語法糖的實現(xiàn)
    2022-07-07
  • Go語言中日期包(time包)的具體使用

    Go語言中日期包(time包)的具體使用

    本文主要介紹了Go語言中日期包的具體使用,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2023-05-05
  • go redis實現(xiàn)滑動窗口限流的方式(redis版)

    go redis實現(xiàn)滑動窗口限流的方式(redis版)

    這篇文章主要介紹了go redis實現(xiàn)滑動窗口限流的方式(redis版),本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-12-12
  • Go語言包管理工具Godep的用法

    Go語言包管理工具Godep的用法

    這篇文章介紹了Go語言包管理工具Godep的用法,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2022-07-07
  • 淺析如何利用Go的plugin機制實現(xiàn)熱更新

    淺析如何利用Go的plugin機制實現(xiàn)熱更新

    熱更新,或稱熱重載或動態(tài)更新,是一種軟件更新技術,允許程序在運行時,不停機更新代碼或資源,本文主要來討論下GO語言是否可以利用plugin機制實現(xiàn)熱更新,感興趣的可以了解下
    2024-04-04
  • Golang中基礎的命令行模塊urfave/cli的用法說明

    Golang中基礎的命令行模塊urfave/cli的用法說明

    這篇文章主要介紹了Golang中基礎的命令行模塊urfave/cli的用法說明,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-12-12

最新評論