從golang-gin-realworld-example-app項目學寫httpapi (五)

https://github.com/gothinkster/golang-gin-realworld-example-app/blob/master/users/middlewares.gogit

中間件定義

package users

import (
    "net/http"
    "strings"

    "github.com/dgrijalva/jwt-go/request"
    "github.com/gin-gonic/gin"
    "github.com/wangzitian0/golang-gin-starter-kit/common"
)

// 請求頭 認證參數前綴標註TOKEN處理, 不使用默認的Bearer標註,而是用TOKEN
// 函數 返回TOKEN字符串值
func stripBearerPrefixFromTokenString(tok string) (string, error) {
    if len(tok) > 5 && strings.ToUpper(tok[0:6]) == "TOKEN " {
        return tok[6:], nil
    }
    return tok, nil
}

// 從請求頭獲取 Authorization 參數內容
var AuthorizationHeaderExtractor = &request.PostExtractionFilter{
    request.HeaderExtractor{"Authorization"},
    stripBearerPrefixFromTokenString,
}

// 從AuthorizationHeaderExtractor獲取 access_token 參數內容
var MyAuth2Extractor = &request.MultiExtractor{
    AuthorizationHeaderExtractor,
    request.ArgumentExtractor{"access_token"},
}

// 函數 更新用戶上下文相關內容
func UpdateContextUserModel(c *gin.Context, my_user_id uint) {
    var myUserModel UserModel
    if my_user_id != 0 {
        db := common.GetDB()
        db.First(&myUserModel, my_user_id)
    }
    c.Set("my_user_id", my_user_id)
    c.Set("my_user_model", myUserModel)
}

// 函數 用戶自定義的中間件, 使用 r.Use(AuthMiddleware(true))
func AuthMiddleware(auto401 bool) gin.HandlerFunc {
    return func(c *gin.Context) {
        // 初始化用戶上下文,用戶ID初值爲0, 用戶初值爲nil
        UpdateContextUserModel(c, 0)

        // 獲取請求中的token內容,並解密爲token對象
        token, err := request.ParseFromRequest(c.Request, MyAuth2Extractor, func(token *jwt.Token) (interface{}, error) {
            b := ([]byte(common.NBSecretPassword))
            return b, nil
        })

        if err != nil {
            // 中間件開關爲true時,返回認證錯誤信息
            if auto401 {
                c.AbortWithError(http.StatusUnauthorized, err)
            }
            return
        }

        // 成功獲取payload信息而且校驗成功,調用函數更新用戶上下文
        if claims, ok := token.Claims.(jwt.MapClaims); ok && token.Valid {
            my_user_id := uint(claims["id"].(float64))
            //fmt.Println(my_user_id, claims["id"])
            UpdateContextUserModel(c, my_user_id)
        }
    }
}
相關文章
相關標籤/搜索