上一篇介紹了如何撰寫及使用middleware,而iris也有許多好用的middleware,所以本篇就來介紹一個好用的middleware jwt。
本文同步放置於此
介紹jwt這個middleware之前還是需要跟大家說明什麼是jwt,接下來再跟大家說明如何使用jwt這個middleware,所以接下來就是跟著這節奏先跟大家介紹什麼是jwt。
在介紹iris怎麼處理jwt之前先說明一下jwt是什麼,jwt就是JSON Web Token的縮寫,詳細內容可以看一下jwt wiki的說明,簡單來說就是一種驗證使用者的協定,這協定可以將使用者的資料加密存放在token之中,因此可以透過這token來取得使用者資料而不需要再與資料庫溝通,所以可以再登入最後將些非敏感的使用者資料存放在token之中,所以接下來再跟大家分享一下如何在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的方法在getTokenHandler可以看到,在這個步驟我們多放一個map到token待之後的範例會介紹如何取出來,最後為了安全措施我們又針對token再加密一次,利用我們的mySecret屬性,完整的語法是tokenString, _ := token.SignedString(mySecret)
讀者們應該有注意到在綁定myAuthenticatedHandler這handler
前有加了另外一個j.Serve
如此可以再執行處理請求前先驗證jwt是否合法,所以只要把要加入驗證的handler
多加一個j.Serve
的前置處理即可。
前面有提到可以把使用者資訊存在token中,那要如何取出來呢,這個解答在myAuthenticatedHandler中就可以看得到,簡單講就是透過user := ctx.Values().Get("jwt").(*jwt.Token)
就可以取得我們放到token的資訊。
最後可以透過foobar := user.Claims.(jwt.MapClaims)
可以取得我們生成token時放進去的資料。
在本例子中是將token放在query string裡面,但是常用的方法是jwt放在header
內,如此可以減少被篡改的機會,那樣要如何實作呢,簡單的講就是將Extractor
的值改成jwt.FromAuthHeader
即可,不過要注意放在header
時要記得在token前加上bearer以及一個空格,不然會驗證失敗喔。
上面的例子產生的例子是永久生效的,不過我們可以使用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上的使用者驗證的方法。