日本免费高清视频-国产福利视频导航-黄色在线播放国产-天天操天天操天天操天天操|www.shdianci.com

學無先后,達者為師

網站首頁 編程語言 正文

go-micro微服務JWT跨域認證問題_Golang

作者:qi66 ? 更新時間: 2023-03-11 編程語言

一 JWT介紹

JWT 英文名是 Json Web Token ,是一種用于通信雙方之間傳遞安全信息的簡潔的、URL安全的表述性聲明規范,經常用在跨域身份驗證。

JWT 以 JSON 對象的形式安全傳遞信息。因為存在數字簽名,因此所傳遞的信息是安全的。

一個JWT Token就像這樣:

eyJhbGci0iJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyX2lkIjoyODAx0DcyNzQ40DMyMzU4NSwiZ
XhwIjoxNTk0NTQwMjkxLCJpc3MiOiJibHV1YmVsbCJ9.1k_ZrAtYGCeZhK3iupHxP1kgjBJzQTVTtX0iZYFx9wU

它是由.分隔的三部分組成,這三部分依次是:

  • 頭部(Header)
  • 負載(Payload)
  • 簽名(Signature)

頭部和負載以jSON形式存在,這就是JWT中的JSON,三部分的內容都分別單獨經過了Base64編
碼,以.拼接成一個JWT Token。

二 JWT優缺點

JWT擁有基于Token的會話管理方式所擁有的一切優勢,不依賴Cookie,使得其可以防止CSRF攻
擊,也能在禁用Cookie的瀏覽器環境中正常運行。

而JWT的最大優勢是服務端不再需要存儲Session,使得服務端認證鑒權業務可以方便擴展,避免存儲
Session所需要引入的Redis等組件,降低了系統架構復雜度。但這也是JWT最大的劣勢,由于有效期
存儲在Token中,JWT Token一旦簽發,就會在有效期內一直可用,無法在服務端廢止,當用戶進行登
出操作,只能依賴客戶端刪除掉本地存儲的JWT Token,如果需要禁用用戶,單純使用JWT就無法做到。

三 JWT使用

1. 導包和數據定義

package token

import (
   "account/config/redis"
   "errors"
   "fmt"
   "github.com/dgrijalva/jwt-go"
   "time"
)

// MyClaims 自定義聲明結構體并內嵌jwt.StandardClaims
// jwt包自帶的jwt.StandardClaims只包含了官方字段
// 我們這里需要額外記錄一個username字段,所以要自定義結構體
// 如果想要保存更多信息,都可以添加到這個結構體中
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) {
   // 創建一個我們自己的聲明
   c := MyClaims{
      UserName, // 自定義字段
      jwt.StandardClaims{
         ExpiresAt: time.Now().Add(TokenExpireDuration).Unix(), // 過期時間
         Issuer:    "Account",                                  // 簽發人
      },
   }
   // 使用指定的簽名方法創建簽名對象
   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 { // 校驗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 自定義聲明結構體并內嵌jwt.StandardClaims
// jwt包自帶的jwt.StandardClaims只包含了官方字段
// 我們這里需要額外記錄一個username字段,所以要自定義結構體
// 如果想要保存更多信息,都可以添加到這個結構體中
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) {
   // 創建一個我們自己的聲明
   c := MyClaims{
      UserName, // 自定義字段
      jwt.StandardClaims{
         ExpiresAt: time.Now().Add(TokenExpireDuration).Unix(), // 過期時間
         Issuer:    "Account",                                  // 簽發人
      },
   }
   // 使用指定的簽名方法創建簽名對象
   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 { // 校驗token
      return mc, nil
   }
   return nil, errors.New("invalid token")
}

四 最后

  • 至此,go-micro微服務JWT跨域認證工作就正式完成。

  • 接下來就開始公用函數的代碼編寫了,希望大家關注博主和關注專欄,第一時間獲取最新內容,每篇博客都干貨滿滿。

原文鏈接:https://www.cnblogs.com/qi66/p/17054818.html

欄目分類
最近更新