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 stringjson:"aud,omitempty"
ExpiresAt int64json:"exp,omitempty"
json:"jti,omitempty"
IssuedAt int64json:"iat,omitempty"
Issuer stringjson:"iss,omitempty"
NotBefore int64json:"nbf,omitempty"
Subject stringjson:"sub,omitempty"
- aud 標識token的接收者.
- exp 過期時間.通常與Unix UTC時間做對比過期後token無效
- jti 是自定義的id號
- iat 簽名發行時間.
- iss 是簽名的發行者.
- nbf 這條token資訊生效時間.這個值可以不設定,但是設定後,一定要大於當前Unix UTC,否則token將會延遲生效.
-
sub 簽名面向的使用者
Signature
通過 header 生明的加密方法生成 簽名.
JWT 包下載
go get github.com/dgrijalva/jwt-go
簡單使用
生成 Token
Payload 結構體
type jwtCustomClaims struct {
jwt.StandardClaims
// 追加自己需要的資訊
Uid uintjson:"uid"
Admin booljson:"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)
}
結果是這樣的.
=== RUNTestCreateToken
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE1NDA2MDc2MzYsImlzcyI6IllEUSIsInVpZCI6MjIyMiwiYWRtaW4iOnRydWV9.oaX63ScaDttkhC31bgjvPSr4PjvBb55UanAA_QP5zpc
--- PASS: TestCreateToken (0.00s)
PASS
解析 Token
解析函式
/**
-
解析 token
*/
func ParseToken(tokenSrt string, SecretKey []byte) (claims jwt.Claims, err error) {
var tokenjwt.Token
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"])
}
結果是這樣的.
=== RUNTestCreateToken
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