每日一库jwt

每日一库jwt

1.JWT介绍

jwt(json web token)是一种用于前后端身份认证的方法,一个jwt由header,payload,和signature组成。

  • header:包含了token类型和算法类型
  • payload:包含了一些用户自定义或jwt预定义的一些数据,每一个数据叫一个claim,注意不要将敏感信息放入
  • signature:将header和payload经过base64编码,加上一个secret密钥,整体经过header中的算法加密后生成

2.JWT的重要结构

2.1Claims

claims是一个实现了Valid方法的interface,Valid方法用于判断该claim是否合法

type Claims struct {
    Valid() error
}

2.2Keyfun

Keyfunc在使用时一般都是返回secret密钥,可以根据Token的种类不同返回不同的密钥.

官方文档:This allows you to use properties in the Header of the token (such as 'kid') to identify which key to use.
type Keyfun func (*Token) {interface(),error}

2.3Mapclaims

一个用于放decode出来的claim的map,有Vaild和一系列VerifyXXX的方法

type MapClaims map[string]interface{}

2.4Parser

用来将tokenstr转换成token

type Parser struct {
    ValidMethods         []string // 有效的加密方法列表,如果不为空,则Parse.Method.Alg()必需是VaildMethods的一种,否则报错
    UseJSONNumber        bool     // Use JSON Number format in JSON decoder
    SkipClaimsValidation bool     // 在解析token时跳过claims的验证
}

2.5SigningMethod

签名方法的接口,可以通过实现这个接口自定义签名方法,jwt-go内置一些实现了SigningMethod的结构体

type SigningMethod interface {
    Verify(signingString, signature string, key interface{}) error // Returns nil if signature is valid
    Sign(signingString string, key interface{}) (string, error)    // Returns encoded signature or error
    Alg() string                                                   // returns the alg identifier for this method (example: 'HS256')
}

2.6StandardClaims

jwt官方规定的一些预定义的payload:

  • iss (issuer):签发人
  • exp (expiration time):过期时间
  • sub (subject):主题
  • aud (audience):受众
  • nbf (Not Before):生效时间
  • iat (Issued At):签发时间
  • jti (JWT ID):编号
type StandardClaims struct {
    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"`
}

2.7Token

Token的结构体

type Token struct {
    Raw       string                 // The raw token.  Populated when you Parse a token
    Method    SigningMethod          // The signing method used or to be used
    Header    map[string]interface{} // The first segment of the token
    Claims    Claims                 // The second segment of the token
    Signature string                 // The third segment of the token.  Populated when you Parse a token
    Valid     bool                   // Is the token valid?  Populated when you Parse/Verify a token
}

2.8ValidationError

定义解析Token时遇到的一些错误

type ValidationError struct {
    Inner  error  // stores the error returned by external dependencies, i.e.: KeyFunc
    Errors uint32 // bitfield.  see ValidationError... constants
    // contains filtered or unexported fields
}

3.基本用法

3.1创建token

type MyCustomClaims struct{
    Username string `json:"username"`
    jwt.StandardClaims
}

secretKey := []byte("Helloworld")

// 直接创建一个token对象,加密方式为HS256
// 下面的代码等于
// token :=  NewWithClaims(jwt.SigningMethodHS256,MyCustomClaims{"Mike"})
token := New(jwt.SigningMethodHS256)
claims := MyCustomClaims{
    "Mike",
}
token.Claims = claims

// 获得最终的tokenStr
tokenStr, err := token.SignedString(secretKey)
    

3.2解析token

var tokenString = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJmb28iOiJiYXIiLCJleHAiOjE1MDAwLCJpc3MiOiJ0ZXN0In0.HE7fK0xOQwFEr4WDgRWj4teRPZ6i3GLwD5YCm6Pwu_c"

token, err := jwt.Parse(tokenString,func(token *jwt.Token)(interface{},error){
    return []byte("Helloworld"), nil
})

// 检查token是否合法
if token.Valid  {
    fmt.Println("token合法")
} else {
    fmt.Println("token不合法, err:",err)
}

3.3jwt+cookie在gin框架中的案例

posted @ 2022-10-18 09:34  惊蛰2020  阅读(69)  评论(0编辑  收藏  举报