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

淺談JWT在GO中的使用方法及原理

 更新時(shí)間:2023年05月26日 10:55:20   作者:POGF  
JWT是一種基于?JSON?的開放標(biāo)準(zhǔn),用于在網(wǎng)絡(luò)應(yīng)用間傳遞聲明,JWT被設(shè)計(jì)為可安全地將用戶身份驗(yàn)證和授權(quán)數(shù)據(jù)作為?JSON?對象在各個(gè)應(yīng)用程序之間傳遞,本文將詳細(xì)給大家介紹JWT原理及在Go中的用法,需要的朋友可以參考下

1. JWT是什么

JWT(JSON Web Token) 是一種基于 JSON 的開放標(biāo)準(zhǔn),用于在網(wǎng)絡(luò)應(yīng)用間傳遞聲明。JWT被設(shè)計(jì)為可安全地將用戶身份驗(yàn)證和授權(quán)數(shù)據(jù)作為 JSON 對象在各個(gè)應(yīng)用程序之間傳遞。

JWT 主要由三部分組成:Header,PayloadSignature。

Header 包含了兩部分信息:令牌的類型(即 JWT)和所使用的算法,通常采用的算法是 HMAC SHA256 或 RSA。

Payload(載荷)包含了要傳遞的信息,可以包括用戶 ID、用戶角色、過期時(shí)間等信息。

Signature(簽名)是使用私鑰對 Header 和 Payload 進(jìn)行簽名生成的,用來驗(yàn)證消息確實(shí)是由發(fā)送方發(fā)出的,以及在傳輸過程中沒有被篡改過。

JWT 的優(yōu)點(diǎn)包括:

  • 無狀態(tài):JWT 本身就包含了用戶信息,不需要再去查詢數(shù)據(jù)庫或者其他的存儲設(shè)備。
  • 安全性:由于JWT包含了簽名,所以一旦JWT被篡改,接收方就能夠檢測到。
  • 便捷性:JWT 的格式是輕量級的,容易傳輸,可以通過 URL、POST 參數(shù)或者在HTTP header中發(fā)送。

使用 JWT 的過程可以分為以下幾個(gè)步驟:

  • 在服務(wù)器端生成一個(gè) JWT,包括 Header、Payload 和 Signature。
  • 在需要驗(yàn)證用戶身份的請求中,將 JWT 添加到 HTTP header 中。
  • 服務(wù)器收到請求后,從 HTTP header 中提取 JWT,并對其進(jìn)行驗(yàn)證,包括簽名驗(yàn)證、Payload 中的信息驗(yàn)證等。
  • 如果驗(yàn)證成功,服務(wù)器返回請求所需的數(shù)據(jù)。
  • 如果驗(yàn)證失敗,則拒絕請求。

JWT 是一種非常流行的身份驗(yàn)證和授權(quán)機(jī)制,被廣泛應(yīng)用于各種互聯(lián)網(wǎng)應(yīng)用中。

2. GO生成JWT

?package jwt
??
?import (
?    "github.com/dgrijalva/jwt-go"
?    "myWeb/config"
?    "time"
?)
??
?type Claims struct {
?    ID ? ? ? int64 ?`json:"id"`
?    Username string `json:"username"`
?    jwt.StandardClaims
?}
??
?// 生成 token
??
?func GenerateToken(id int64 ,username string) (string, error) {
?    // 定義 token 的過期時(shí)間
?    expireTime := time.Now().Add(config.ExpireDuration).Unix()
??
?    // 創(chuàng)建一個(gè)自定義的 Claims
?    claims := &Claims{
? ? ? ? ?ID:id,
?        Username: username,
?        StandardClaims: jwt.StandardClaims{
?            ExpiresAt: expireTime,
?            IssuedAt: ?time.Now().Unix(),
?            Issuer: ? ?"pogf",
?        },
?    }
??
?    // 使用 JWT 簽名算法生成 token
?    token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
??
?    // 將 token 進(jìn)行加鹽加密
?    tokenString, err := token.SignedString(config.JwtKey)
?    if err != nil {
?        return "", err
?    }
??
?    return tokenString, nil
?}
??

詳細(xì)分析:

?type Claims struct {
?    ID ? ? ? int64 ?`json:"id"`
?    Username string `json:"username"`
?    jwt.StandardClaims
?}

該結(jié)構(gòu)體用于定義 JWT 的 payload,也就是 JWT 載荷中存儲的信息。其中,IDUsername 用于標(biāo)識用戶身份,jwt.StandardClaims 則是 JWT 的標(biāo)準(zhǔn)聲明,包含了 JWT 的一些基本信息,比如過期時(shí)間、簽發(fā)時(shí)間等。在創(chuàng)建 JWT 時(shí),我們需要將這個(gè)結(jié)構(gòu)體傳入,以便生成 JWT 的 payload。在驗(yàn)證 JWT 時(shí),我們也需要解析出這個(gè)結(jié)構(gòu)體,以便獲取 JWT 中存儲的用戶身份信息。

?expireTime := time.Now().Add(config.ExpireDuration).Unix()

這行代碼的作用是根據(jù)配置文件中的過期時(shí)間(config.ExpireDuration)計(jì)算出當(dāng)前時(shí)間加上過期時(shí)間后的 Unix 時(shí)間戳(expireTime),以便在生成 JWT 時(shí)設(shè)置過期時(shí)間。

time.Now() 函數(shù)返回當(dāng)前的本地時(shí)間(time.Time 類型),Add() 方法則用于對時(shí)間進(jìn)行加減,參數(shù)是 time.Duration 類型,表示時(shí)間間隔。因此,time.Now().Add(config.ExpireDuration) 計(jì)算出的是過期時(shí)間的時(shí)間點(diǎn)。接著,調(diào)用 Unix() 方法將時(shí)間點(diǎn)轉(zhuǎn)換為對應(yīng)的 Unix 時(shí)間戳(int64 類型),用于設(shè)置 JWT 的過期時(shí)間。

?    claims := &Claims{
? ? ? ? ?ID:id,
?        Username: username,
?        StandardClaims: jwt.StandardClaims{
?            ExpiresAt: expireTime,
?            IssuedAt: ?time.Now().Unix(),
?            Issuer: ? ?"pogf",
?        },
?    }

這段代碼是在創(chuàng)建一個(gè)包含用戶身份信息的JWT token,其中Claims結(jié)構(gòu)體定義了JWT token中所包含的信息,包括IDUsername,以及jwt.StandardClaims結(jié)構(gòu)體中的標(biāo)準(zhǔn)信息,如ExpiresAt(過期時(shí)間),IssuedAt(簽發(fā)時(shí)間)和Issuer(簽發(fā)者)等。

在上述代碼中,IDUsername分別代表用戶的唯一標(biāo)識和用戶名,這些信息將被編碼到JWT token中。StandardClaims中的信息則用于控制JWT token的生命周期和有效性。

ExpiresAt表示JWT token的過期時(shí)間,超過這個(gè)時(shí)間后,JWT token將失效,無法再被使用。IssuedAt表示JWT token的簽發(fā)時(shí)間,Issuer表示JWT token的簽發(fā)者,這些信息可以幫助驗(yàn)證JWT token的合法性。

?token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)

它首先創(chuàng)建了一個(gè) JWT 對象 token,其中包含了指定的簽名方法 jwt.SigningMethodHS256 和聲明 claims。

JWT 中有三個(gè)部分:頭部(Header)、載荷(Payload)和簽名(Signature)。頭部指定了所使用的簽名算法,例如 HS256 表示使用 HMAC-SHA256 算法進(jìn)行簽名。載荷是 JWT 中用來攜帶實(shí)際信息的部分,其中可以自定義各種聲明信息,例如上面代碼中的 claims 變量。簽名是將頭部和載荷進(jìn)行加密得到的一串字符串,用于驗(yàn)證 JWT 是否合法。

因此,這段代碼就是創(chuàng)建了一個(gè)帶有指定聲明的 JWT 對象,并指定了使用 HS256 算法進(jìn)行簽名。

?    // 將 token 進(jìn)行加鹽加密
?    tokenString, err := token.SignedString(config.JwtKey)
?    if err != nil {
?        return "", err
?    }
?    return tokenString, nil

加鹽加密的目的是為了增加數(shù)據(jù)的安全性,防止攻擊者使用彩虹表等方式對加密后的數(shù)據(jù)進(jìn)行破解。加鹽是指在原始數(shù)據(jù)的基礎(chǔ)上加上一些隨機(jī)的字符串或數(shù)字,使得同樣的原始數(shù)據(jù)加鹽后的結(jié)果是不同的。加密是指將原始數(shù)據(jù)和鹽一起通過某種加密算法進(jìn)行加密,得到一串密文。密文是不能被破解的,只能通過使用同樣的鹽和加密算法對原始數(shù)據(jù)進(jìn)行加密后得到相同的密文來驗(yàn)證數(shù)據(jù)的真實(shí)性。

在JWT中,加鹽加密可以有效地防止攻擊者偽造token,從而保障應(yīng)用的安全性。具體地,JWT在生成token時(shí)會使用指定的秘鑰對payload進(jìn)行簽名,這個(gè)秘鑰就是加鹽的一部分。只有使用相同的秘鑰才能對payload進(jìn)行解密并驗(yàn)證token的真實(shí)性。因此,只有知道秘鑰的人才能生成有效的token,從而有效地保護(hù)了應(yīng)用的安全性。

單元測試

?func TestGenerateToken(t *testing.T) {
?    token, err := GenerateToken(1, "wyf")
?    if err != nil {
?        t.Fatal(err)
?    }
?    t.Logf(token)
?}
??
?$ go test -v -run  TestGenerateToken
?=== RUN ? TestGenerateToken
? ?  jwt_test.go:10: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6MSwidXNlcm5hbWUiOiJ3eWYiLCJleHAiOjE2ODM4NzU4NjcsImlhdCI6MTY4Mzc4OTQ2NywiaXNzIjoicG9nZiJ9.rXzf1fzidsfwe4HRBt7JN_NxAxUceD0HxdpCQsbPuFc
?--- PASS: TestGenerateToken (0.00s)
?PASS
?ok ? ?  myWeb/util ? ? ?0.058s
??

3. GO解析JWT

相關(guān)函數(shù)介紹

?func ParseToken(tokenString string) (*Claims, error) {
?    // 解析 token
?    token, err := jwt.ParseWithClaims(tokenString, &Claims{}, func(token *jwt.Token) (interface{}, error) {
?        return config.JwtKey, nil
?    })
??
?    if err != nil {
?        return nil, err
?    }
??
?    if claims, ok := token.Claims.(*Claims); ok && token.Valid {
?        return claims, nil
?    } else {
?        return nil, jwt.NewValidationError("invalid token", jwt.ValidationErrorClaimsInvalid)
?    }
?}
??
?func ParseWithClaims(tokenString string, claims Claims, keyFunc Keyfunc) (*Token, error) {
?    return new(Parser).ParseWithClaims(tokenString, claims, keyFunc)
?}

jwt.ParseWithClaims()函數(shù)用于解析并驗(yàn)證JWT token,并提取出其中的Claims數(shù)據(jù)結(jié)構(gòu)。該函數(shù)接受三個(gè)參數(shù):

  • tokenString: 要解析的JWT token字符串。
  • claims: 一個(gè)結(jié)構(gòu)體指針,用于接收從JWT token中解析出來的Claims數(shù)據(jù)。
  • keyFunc: 一個(gè)回調(diào)函數(shù),用于驗(yàn)證JWT token的簽名。在函數(shù)內(nèi)部,可以對JWT token的簽名進(jìn)行驗(yàn)證,比如檢查簽名是否正確、是否過期等等。該函數(shù)需要返回一個(gè)interface{}類型的值,表示用于驗(yàn)證簽名的密鑰。如果驗(yàn)證成功,應(yīng)該返回一個(gè)非空的密鑰;如果驗(yàn)證失敗,應(yīng)該返回一個(gè)nil值和相應(yīng)的錯(cuò)誤信息。

在上述代碼中,&Claims{}作為第二個(gè)參數(shù)傳遞給了jwt.ParseWithClaims()函數(shù),這表示從JWT token中解析出的Claims數(shù)據(jù)將被解碼為該結(jié)構(gòu)體類型。第三個(gè)參數(shù)是一個(gè)匿名函數(shù),用于驗(yàn)證JWT token的簽名,config.JwtKey被作為用于驗(yàn)證簽名的密鑰傳遞。如果JWT token驗(yàn)證通過,jwt.ParseWithClaims()函數(shù)將返回一個(gè)*jwt.Token類型的指針,其中包含了解碼后的Claims數(shù)據(jù),以及一些其他的元數(shù)據(jù)。如果驗(yàn)證失敗,函數(shù)將返回相應(yīng)的錯(cuò)誤信息。

單元測試

?func TestParseToken(t *testing.T) {
?    c, err := ParseToken("eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6MSwidXNlcm5hbWUiOiJ3eWYiLCJleHAiOjE2ODM4NzU4NjcsImlhdCI6MTY4Mzc4OTQ2NywiaXNzIjoicG9nZiJ9.rXzf1fzidsfwe4HRBt7JN_NxAxUceD0HxdpCQsbPuFc")
?    if err != nil {
?        t.Fatal(err)
?    }
?    t.Log(*c)
?}
?$ go test -v -run  TestParseToken
?=== RUN ? TestParseToken
? ?  jwt_test.go:18: {1 wyf { 1683875867 ?1683789467 pogf 0 }}
?--- PASS: TestParseToken (0.00s)
?PASS
?ok ? ?  myWeb/util ? ? ?0.796s

4. 總結(jié)

JWT(JSON Web Token)是一種用于身份驗(yàn)證的開放標(biāo)準(zhǔn),它通過在用戶和服務(wù)器之間傳遞被加密的 JSON 對象來安全地傳輸信息。JWT 由三個(gè)部分組成:頭部、載荷和簽名。其中,頭部包含加密算法和 token 類型等信息,載荷包含存儲在 token 中的用戶信息,簽名用于驗(yàn)證 token 的真實(shí)性和完整性。

使用 JWT 時(shí)需要注意以下幾點(diǎn):

  • 避免在 JWT 中存儲敏感信息,比如密碼、銀行卡號等。
  • 需要使用安全的算法來簽名和加密 JWT,比如使用 HMAC 或 RSA 加密。
  • JWT 中包含的用戶信息不應(yīng)該過多,只保留必要的信息即可。
  • 在使用 JWT 進(jìn)行身份驗(yàn)證時(shí),需要防止令牌被盜用??梢圆捎靡恍┘夹g(shù)手段,比如限制令牌的有效期、限制令牌的使用次數(shù)等。
  • 在生成 JWT 時(shí)需要注意加鹽加密,以提高安全性。
  • 在解析 JWT 時(shí)需要對 JWT 進(jìn)行校驗(yàn),以保證 JWT 的真實(shí)性和完整性。
  • 最后,需要注意遵循安全的開發(fā)實(shí)踐,保障應(yīng)用的安全性。

以上就是淺談JWT原理以及在GO中的使用方法的詳細(xì)內(nèi)容,更多關(guān)于JWT及在GO中的使用的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • Golang學(xué)習(xí)筆記(三):控制流

    Golang學(xué)習(xí)筆記(三):控制流

    這篇文章主要介紹了Golang學(xué)習(xí)筆記(三):控制流,本文講解了IF、FOR、SWITCH、goto、break、continue等控制流語句的使用實(shí)例,需要的朋友可以參考下
    2015-05-05
  • Go利用反射reflect實(shí)現(xiàn)獲取接口變量信息

    Go利用反射reflect實(shí)現(xiàn)獲取接口變量信息

    反射是通過實(shí)體對象獲取反射對象(Value、Type),然后可以操作相應(yīng)的方法。本文將利用Go語言中的反射reflect實(shí)現(xiàn)獲取接口變量信息,需要的可以參考一下
    2022-05-05
  • Golang使用第三方包viper讀取yaml配置信息操作

    Golang使用第三方包viper讀取yaml配置信息操作

    這篇文章主要介紹了Golang使用第三方包viper讀取yaml配置信息操作,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-12-12
  • gin使用自定義結(jié)構(gòu)綁定表單數(shù)據(jù)的示例代碼

    gin使用自定義結(jié)構(gòu)綁定表單數(shù)據(jù)的示例代碼

    這篇文章主要介紹了gin使用自定義結(jié)構(gòu)綁定表單數(shù)據(jù)的示例代碼,代碼簡單易懂,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-11-11
  • Go實(shí)現(xiàn)比較時(shí)間大小

    Go實(shí)現(xiàn)比較時(shí)間大小

    這篇文章主要介紹了Go實(shí)現(xiàn)比較時(shí)間大小的方法和示例,非常的簡單實(shí)用,有需要的小伙伴可以參考下。
    2015-04-04
  • vscode插件設(shè)置之Golang開發(fā)環(huán)境配置全過程

    vscode插件設(shè)置之Golang開發(fā)環(huán)境配置全過程

    go語言開發(fā)選擇vscode作為IDE工具也是一個(gè)不錯(cuò)的選擇,下面這篇文章主要給大家介紹了關(guān)于vscode插件設(shè)置之Golang開發(fā)環(huán)境配置的相關(guān)資料,文中通過圖文介紹的非常詳細(xì),需要的朋友可以參考下
    2022-12-12
  • Go語言中g(shù)oroutine的使用

    Go語言中g(shù)oroutine的使用

    本文主要介紹了Go語言中g(shù)oroutine的使用,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-06-06
  • Golang 正則匹配效率詳解

    Golang 正則匹配效率詳解

    這篇文章主要介紹了Golang 正則匹配效率詳解,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2021-04-04
  • 詳解Go語言中用 os/exec 執(zhí)行命令的五種方法

    詳解Go語言中用 os/exec 執(zhí)行命令的五種方法

    這篇文章主要介紹了Go語言中用 os/exec 執(zhí)行命令的五種方法,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-11-11
  • Golang常量iota的使用實(shí)例

    Golang常量iota的使用實(shí)例

    今天小編就為大家分享一篇關(guān)于Golang常量iota的使用實(shí)例,小編覺得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來看看吧
    2019-01-01

最新評論