Iris jwt 使用

jwt分爲三個部分:git

​ 一、header,用來存儲算法和token類型等信息
​ 二、payload, 一些簡單的信息
​ 三、簽名,來驗證token是否合法github

iris-jwt

這是初始化jwt中間件的配置參數。

type Config struct {
    ValidationKeyGetter jwt.Keyfunc
    // 用來設置請求中經過那個key獲取Token,默認是 "jwt", user := ctx.Values().Get("jwt").(*jwt.Token)
    ContextKey string
    ErrorHandler errorHandler
    CredentialsOptional bool
    Extractor TokenExtractor
    Debug bool
    EnableAuthOnOptions bool
    SigningMethod jwt.SigningMethod
    // 是否驗證過時時間,若是爲true,則驗證Claims中的exp字段。
    Expiration bool
}

初始化jwt中間件:
    jwtHandler := jwtmiddleware.New(jwtmiddleware.Config{
        ValidationKeyGetter: func(token *jwt.Token) (interface{}, error) {
            return []byte("My Secret"), nil
        },
        SigningMethod: jwt.SigningMethodHS256,
    })

使用中間件:
    needauth := app.Party("/auth", jwtHandler.Serve)
    {   // /auth路徑下全部的請求都須要jwt驗證
        needauth.Get("/ping", myHandler)
    }

驗證過程:
    一、token能夠設置從Header中獲取FromAuthHeader(ctx context.Context), 也能夠從Parameter獲取FromParameter(param string) TokenExtractor, 也能夠自定義一個,還能夠對加密過的token解密等。

    二、獲取完token以後,此時token是個字符串,未通過驗證,也爲未成對象。解析成對象以後,經過keyFun返回的的key驗證token,返回token對象。最後執行ctx.Values().Set(m.Config.ContextKey, parsedToken)將解析完的token放到jwt這個key中。
    上面說的keyFun:
    jwtHandler := jwtmiddleware.New(jwtmiddleware.Config{
        ValidationKeyGetter: func(token *jwt.Token) (interface{}, error) {
            return []byte("My Secret"), nil
        },
        SigningMethod: jwt.SigningMethodHS256,
    })
    這個方法接收Token對象,返回一個用於驗證token的key。這裏會有什麼騷操做呢,好像能夠拿到Token胡搞一番,返回一個key。做者的目的好像是能夠根據token返回不一樣的key。
這裏可能爲了不token被盜,使用動態的key,key值能夠經過token的時間來生成, 快過時了從新生成新的key。

每次生成新的token都須要用戶名和密碼,用戶名和密碼保存在js中,瀏覽器關閉,而且token過時後則須要從新登錄。即便token被盜,時間也不會過久。
因爲js中保存了用戶名和密碼,即便token過時了,也能從新生成token。

或者使用ip認證也能夠。

    三、檢查完了以後進入下一個中間件,或者Handler。
    

設置token的過程:
    一、生成token對象,而後簽名,完了。
        token := jwt.NewWithClaims(jwt.SigningMethodHS256, jwt.MapClaims{
            "useewhat": "eyJ1c2Vld2hhdCI6IiJ9",
        })
        tokenString, _ := token.SignedString([]byte("My Secret"))
        ctx.Header("Authorization", "bearer "+tokenString)
    
    // Claims也能夠是: jwt.StandardClaims
    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"`
    }

安全性

因爲jwt的payload部分也是可見的,能夠把信息加密後再放到Claims中,獲取到Claims後,再經過一箇中間件解密。
也能夠把上面的tokenString的payload部分加密, 收到請求後,自定義一個FromAuthHeader來解密payload部分。

過時時間

處於安全考慮,能夠設置一個固定的時間,不進行更新jwt。過時了以後須要從新登錄。可能會出現用戶用着的時候忽然退出登錄的狀況。
也能夠更新token,不過若是token被盜以後很難回收。由於key是固定的。啊,想到騷操做了。返回上面的文檔。

下面是一個寫的慘不忍睹的例子:算法

import (
    "github.com/kataras/iris"

    "github.com/dgrijalva/jwt-go"
    jwtmiddleware "github.com/iris-contrib/middleware/jwt"
)

type Response struct {
    Text string `json:"text"`
}

func main() {
    app := iris.New()

    myHandler := func(ctx iris.Context) {
        user := ctx.Values().Get("jwt").(*jwt.Token)

        ctx.Writef("This is an authenticated request\n")
        ctx.Writef("Claim content:\n")

        ctx.Writef("%s", user.Signature)
    }

    jwtHandler := jwtmiddleware.New(jwtmiddleware.Config{
        ValidationKeyGetter: func(token *jwt.Token) (interface{}, error) {
            return []byte("My Secret"), nil
        },
        SigningMethod: jwt.SigningMethodHS256,
    })

    getjwt := func(ctx iris.Context) {
        token := jwt.NewWithClaims(jwt.SigningMethodHS256, jwt.MapClaims{
            "useewhat": "我已經加過密了,你看不到",
        })

        tokenString, _ := token.SignedString([]byte("My Secret"))
        ctx.Header("Authorization", "bearer "+tokenString)

        response := "Get it"

        ctx.JSON(response)
    }

    needauth := app.Party("/", jwtHandler.Serve)
    {
        needauth.Get("/ping", myHandler)
    }

    app.Get("/getjwt", getjwt)

    app.Run(iris.Addr("localhost:3001"))
}
相關文章
相關標籤/搜索