Iris 這個在 go 語言上地表最快的網頁框架-iris的jwt

jwt

上一篇介紹了如何撰寫及使用middleware,而iris也有許多好用的middleware,所以本篇就來介紹一個好用的middleware jwt。

jwt

介紹jwt這個middleware之前還是需要跟大家說明什麼是jwt,接下來再跟大家說明如何使用jwt這個middleware,所以接下來就是跟著這節奏先跟大家介紹什麼是jwt。

什麼是jwt

在介紹iris怎麼處理jwt之前先說明一下jwt是什麼,jwt就是JSON Web Token的縮寫,詳細內容可以看一下jwt wiki的說明,簡單來說就是一種驗證使用者的協定,這協定可以將使用者的資料加密存放在token之中,因此可以透過這token來取得使用者資料而不需要再與資料庫溝通,所以可以再登入最後將些非敏感的使用者資料存放在token之中,所以接下來再跟大家分享一下如何在iris使用jwt。

iris上如何使用jwt

因為iris有內建一個middleware來處理jwt,所以我們藉由iris jwt example這個範例來說明一下在iris如何使用jwt這個middleware來處理JSON Web Token,首先先看一下下列例子

package main

import (
    "github.com/kataras/iris/v12"
    "github.com/iris-contrib/middleware/jwt"
)

var mySecret = []byte("My Secret")

// generate token to use.
func getTokenHandler(ctx iris.Context) {
    token := jwt.NewTokenWithClaims(jwt.SigningMethodHS256, jwt.MapClaims{
        "foo": "bar",
    })

    // Sign and get the complete encoded token as a string using the secret
    tokenString, _ := token.SignedString(mySecret)

    ctx.HTML(`Token: ` + tokenString + `<br/><br/>
<a href="/secured?token=` + tokenString + `">/secured?token=` + tokenString + `</a>`)
}

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

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

    foobar := user.Claims.(jwt.MapClaims)
    for key, value := range foobar {
        ctx.Writef("%s = %s", key, value)
    }
}

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

    j := jwt.New(jwt.Config{
        ValidationKeyGetter: func(token *jwt.Token) (interface{}, error) {
            return mySecret, nil
        },

        // Extract by the "token" url.
        // There are plenty of options.
        // The default jwt's behavior to extract a token value is by
        // the `Authorization: Bearer $TOKEN` header.
        Extractor: jwt.FromParameter("token"),
        // When set, the middleware verifies that tokens are
        // signed with the specific signing algorithm
        // If the signing method is not constant the `jwt.Config.ValidationKeyGetter` callback
        // can be used to implement additional checks
        // Important to avoid security issues described here:
        // https://auth0.com/blog/2015/03/31/critical-vulnerabilities-in-json-web-token-libraries/
        SigningMethod: jwt.SigningMethodHS256,
    })

    app.Get("/", getTokenHandler)
    app.Get("/secured", j.Serve, myAuthenticatedHandler)

    // j.CheckJWT(Context) error can be also used inside handlers.

    app.Listen(":8080")
}

這裡要關注的是getTokenHandler與myAuthenticatedHandler這兩個handler
,接下來我們分段說明jwt的用法。

生成jwt

生成jwt的方法在getTokenHandler可以看到,在這個步驟我們多放一個map到token待之後的範例會介紹如何取出來,最後為了安全措施我們又針對token再加密一次,利用我們的mySecret屬性,完整的語法是tokenString, _ := token.SignedString(mySecret)

驗證jwt

讀者們應該有注意到在綁定myAuthenticatedHandler這handler前有加了另外一個j.Serve如此可以再執行處理請求前先驗證jwt是否合法,所以只要把要加入驗證的handler多加一個j.Serve的前置處理即可。

由jwt中取得使用者資訊

前面有提到可以把使用者資訊存在token中,那要如何取出來呢,這個解答在myAuthenticatedHandler中就可以看得到,簡單講就是透過user := ctx.Values().Get("jwt").(*jwt.Token)就可以取得我們放到token的資訊。
最後可以透過foobar := user.Claims.(jwt.MapClaims)可以取得我們生成token時放進去的資料。

請求時jwt放哪裡

在本例子中是將token放在query string裡面,但是常用的方法是jwt放在header內,如此可以減少被篡改的機會,那樣要如何實作呢,簡單的講就是將Extractor的值改成jwt.FromAuthHeader即可,不過要注意放在header時要記得在token前加上bearer以及一個空格,不然會驗證失敗喔。

會逾期的jwt

上面的例子產生的例子是永久生效的,不過我們可以使用jwt產生使用期限,請大家看一下下面的例子

token := jwt.NewTokenWithClaims(jwt.SigningMethodHS256, jwt.MapClaims{
             "foo": "bar",
             "exp": time.Now().Add(time.Hour * time.Duration(12)).Unix() // 合法的時間戳
             "iat": time.Now().Unix() // 簽發token的時間戳

    })

上面的例子將token加上簽發時間戳以及合法的時間戳,最後在生成middleware的config加上以下參數即可


    j := jwt.New(jwt.Config{
            ValidationKeyGetter: func(token *jwt.Token) (interface{}, error) {
            return mySecret, nil
        },
            Extractor: jwt.FromParameter("token"),
            SigningMethod: jwt.SigningMethodHS256,
            Expiration:true,
    })

結論

本篇跟大家介紹一個驗證的利器jwt,並且介紹如何在iris使用jwt這個middleware,希望能夠幫助大家瞭解關於iris上的使用者驗證的方法。

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *