token驗證是一種web常用的身分識別驗證手段,在這裡不討論它的具體實現
我需要在golang裡實現token驗證,Web架構是Gin(當然這與架構沒有關係)
步驟如下
- 從
request
擷取tokenstring
- 將
tokenstring
轉化為未解密的token對象
- 將
未解密的token對象
解密得到解密後的token對象
- 從
解密後的token對象
裡取參數
一、擷取解密後的token
該函數根據request,獲得tokenstring,並轉為未解密token對象,解密後得到解密token對象
import github.com/dgrijalva/jwt-go/request
request.ParseFromRequest(req *http.Request, extractor Extractor, keyFunc jwt.Keyfunc)
req
即為http請求
extractor
是一個實現了Extractor介面
的對象,該介面需要實現的函數是ExtractToken(*http.Request) (string, error)
,用於從http請求中提取tokenstring
keyFunc
是一個函數,需要接受一個“未解密的token”,並返回Secretkey的位元組和錯誤資訊
func GetToken(r *http.Request) (token *jwt.Token, err error) { //由request擷取token t := T{} // t是已經實現extract介面的對象,對request進行處理得到tokenString並產生為解密的token // request.ParseFromRequest的第三個參數是一個keyFunc,具體的直接看原始碼 // 該keyFunc參數需要接受一個“未解密的token”,並返回Secretkey的位元組和錯誤資訊 // keyFunc被調用並傳入未解密的token參數,返回解密好的token和可能出現的錯誤 // 若解密是正確的,那麼返回的token.valid = true return request.ParseFromRequest(r, t, func(token *jwt.Token) (interface{}, error) { return []byte(Secretkey), nil })}
二、(獲得payload的資訊)從token對象裡獲得參數(key)對應的值
func GetIdFromClaims(key string, claims jwt.Claims) string { v := reflect.ValueOf(claims) if v.Kind() == reflect.Map { for _, k := range v.MapKeys() { value := v.MapIndex(k) if fmt.Sprintf("%s", k.Interface()) == key { return fmt.Sprintf("%v", value.Interface()) } } } return ""}// 樣本 :GetIdFromClaims("username", token.claims) 其中token是已經解密的token
三、函數嵌套關係
以下列舉了在jwt解析過程所調用的jwt-go庫函數
func: request.ParseFromRequest(req, extractor, keyFunc)(*Token, error)
struct: request.fromRequestParser{req, extractor, claims=nil, parser=nil}
func: parser.ParseWithClaims(tokenString, claims, keyFunc)(*Token, error)
parser.ParseUnverified(tokenString string, claims Claims) (token *Token, parts []string, err error)