- 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