golang JWT 包生成 Token, 驗證 Token


  • JSON Web token 簡稱 jwt 是一種輕量級的規范
  • 常用與用戶認證
  • 大致由 3 部分構成:
  • Header (頭部)
  • Payload (載荷)
  • Signature (簽名)
  • .拼接
  • Token = Header + '.' + Payload + '.' + Signature

Header

用來表明簽名的加密算法 token 類型等。

{ 
"typ": "JWT",
"alg": "HS256"lag
}

以上 JSON 轉為 base64 生成 header

Payload

Payload 記錄你需要的信息。 其中應該包含 Claims

Claims

Audience string `json:"aud,omitempty"`  
ExpiresAt int64 `json:"exp,omitempty"`  
Id string `json:"jti,omitempty"` 
IssuedAt int64 `json:"iat,omitempty"`  
Issuer string `json:"iss,omitempty"`  
NotBefore int64 `json:"nbf,omitempty"`  
Subject string `json:"sub,omitempty"`
1. aud 標識token的接收者.
2. exp 過期時間.通常與Unix UTC時間做對比過期后token無效
3. jti 是自定義的id號 
4. iat 簽名發行時間.
5. iss 是簽名的發行者.
6. nbf 這條token信息生效時間.這個值可以不設置,但是設定后,一定要大於當前Unix UTC,否則token將會延遲生效.
7. sub 簽名面向的用戶

Signature

通過 header 生明的加密方法生成 簽名。

JWT 包下載

go get github.com/dgrijalva/jwt-go

簡單使用

生成 Token

Payload 結構體

type jwtCustomClaims struct {
	jwt.StandardClaims

	// 追加自己需要的信息
	Uid   uint `json:"uid"`
	Admin bool `json:"admin"`
}

編寫生成 token 的函數

/**
 * 生成 token
 * SecretKey 是一個 const 常量
 */
func CreateToken(SecretKey []byte, issuer string, Uid uint, isAdmin bool) (tokenString string, err error) {
	claims := &jwtCustomClaims{
		jwt.StandardClaims{
			ExpiresAt: int64(time.Now().Add(time.Hour * 72).Unix()),
			Issuer:    issuer,
		},
		Uid,
		isAdmin,
	}
	token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
	tokenString, err = token.SignedString(SecretKey)
	return
}

test 一下

func TestCreateToken(t *testing.T)  {  
   token, _ := CreateToken([]byte(SecretKey), "YDQ", 2222, true)  
   fmt.Println(token)
}

結果是這樣的。

=== RUN   TestCreateToken

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE1NDA2MDc2MzYsImlzcyI6IllEUSIsInVpZCI6MjIyMiwiYWRtaW4iOnRydWV9.oaX63ScaDttkhC31bgjvPSr4PjvBb55UanAA_QP5zpc
--- PASS: TestCreateToken (0.00s)
PASS
解析 Token

解析函數

/**
 * 解析 token
 */
func ParseToken(tokenSrt string, SecretKey []byte) (claims jwt.Claims, err error) {
	var token *jwt.Token
	token, err = jwt.Parse(tokenSrt, func(*jwt.Token) (interface{}, error) {
		return SecretKey, nil
	})
	claims = token.Claims
	return
}
合並到一起測試。
func TestCreateToken(t *testing.T) {
	token, _ := CreateToken([]byte(SecretKey), "YDQ", 2222, true)
	fmt.Println(token)

	claims, err := ParseToken(token, []byte(SecretKey))
	if nil != err {
		fmt.Println(" err :", err)
	}
	fmt.Println("claims:", claims)
	fmt.Println("claims uid:", claims.(jwt.MapClaims)["uid"])
}
結果是這樣的。
 
=== RUN   TestCreateToken

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE1NDA2MDgyODgsImlzcyI6IllEUSIsInVpZCI6MjIyMiwiYWRtaW4iOnRydWV9.8wE-_Wx-DHI2GMXJ9KT5JOndst2CCEaUNEIGDy9CUbM
claims: map[exp:1.540608288e+09 iss:YDQ uid:2222 admin:true]
claims uid: 2222
--- PASS: TestCreateToken (0.00s)
PASS

  


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM