使用jwt生成token
JWT是什麼
Json web token (JWT), 是為了在網絡應用環境間傳遞聲明而執行的一種基于JSON的開放标準((RFC 7519).該token被設計為緊湊且安全的,特别适用于分布式站點的單點登入(SSO)場景。JWT的聲明一般被用來在身份提供者和服務提供者間傳遞被認證的使用者身份資訊,以便于從資源伺服器擷取資源,也可以增加一些額外的其它業務邏輯所必須的聲明資訊,該token也可直接被用于認證,也可被加密。
JWT組成部分
- Header(預設辨別, 和加密算法)
- Claims(載荷)
Audience string `json:"aud,omitempty"` //token接收者 ExpiresAt int64 `json:"exp,omitempty"` //過期時間 Id string `json:"jti,omitempty"` //自定義id号 IssuedAt int64 `json:"iat,omitempty"` //簽名發行時間 Issuer string `json:"iss,omitempty"` //簽名發行者 NotBefore int64 `json:"nbf,omitempty"` //token資訊生效時間 Subject string `json:"sub,omitempty"` //簽名面向的使用者
- Signature(加密簽名)
go中應用
使用到的開源庫
go get github.com/urfave/negroni //web中間件
go get github.com/dgrijalva/jwt-go
go get github.com/dgrijalva/jwt-go/request
生成token代碼(根據Wangjiaxing123/JwtDemo 修改)
//定義載荷
type CustomClaims struct {
Username string `json:"username"` //1
ExpireTime int64 `json:"expire_time"` //2這些可以自己随意設定
jwt.StandardClaims //過期時間等初始化定義在這個結構體中
}
type JWT struct {
SigningKey []byte
}
//初始化設定sign
func NewJWT() *JWT {
return &JWT{
[]byte(GetSignKey()),
}
}
//根據載荷建立一個token
func (j *JWT) CreatToken(claims CustomClaims) (string, error) {
token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
return token.SignedString(j.SigningKey)
}
驗證token
//錯誤資訊常量
var (
TokenExpired = errors.New("Token is expired")
TokenNotValidYet = errors.New("Token not active yet")
TokenMalformed = errors.New("That's not even a token")
TokenInvalid = errors.New("Couldn't handle this token:")
SignKey = "lottery"
)
//解析token
func (j *JWT) ParseToken(tokenString string) (*CustomClaims, error) {
//根據jwt-go庫代碼解析token
token, err := jwt.ParseWithClaims(tokenString, &CustomClaims{}, func(token *jwt.Token) (i interface{}, e error) {
return j.SigningKey, nil
})
//輸出錯誤資訊
if err != nil {
if ve, ok := err.(*jwt.ValidationError); ok {
if ve.Errors & jwt.ValidationErrorMalformed != 0 {
return nil, TokenMalformed
}else if ve.Errors & jwt.ValidationErrorExpired != 0 {
return nil, TokenExpired
}else if ve.Errors & jwt.ValidationErrorNotValidYet != 0 {
return nil, TokenNotValidYet
}else {
return nil, TokenInvalid
}
}
}
//如果驗證成功則傳回載體
if Claims, ok := token.Claims.(*CustomClaims); ok && token.Valid {
return Claims, nil
}
return nil, TokenInvalid
}