go實現類似與spring的全域性上下文獲取getPrincipal()

demon_h發表於2021-02-04
import "github.com/cosmos72/gls"

/**
設定key-value
*/
func SetVal(key interface{}, val interface{}) {
    gls.Set(key, val)
}

/**
獲取值
*/
func GetVal(key interface{}) string {
    v, ok := gls.Get(key)
    if ok {
        return v.(string)
    }
    return ""
}

使用方式,在jwt鑑權的時候將使用者資訊存入SetVal

/**
jwt鑑權
*/
func JWTAuthMiddleware() func(c *gin.Context) {
    return func(c *gin.Context) {
        uu := c.Request.URL
        //log.Infof("")
        //log.Infof("請求url = %s" ,uu.Path)

        //無需token請求url
        if IsContain(config.NO_TOKENS, uu.Path) {
            c.Next()
            return
        }

        //Log("uu", uu)
        // 客戶端攜帶Token有三種方式 1.放在請求頭 2.放在請求體 3.放在URI
        // 這裡假設Token放在Header的Authorization中,並使用Bearer開頭
        // 這裡的具體實現方式要依據你的實際業務情況決定
        authHeader := c.Request.Header.Get("Authorization")
        if authHeader == "" {
            Fail(c, "請求頭中Authorization為空")
            c.Abort()
            return
        }
        // 按空格分割
        //parts := strings.SplitN(authHeader, " ", 2)
        //if !(len(parts) == 2 && parts[0] == "Bearer") {
        // c.JSON(http.StatusOK, gin.H{
        //  "code": 2004,
        //  "msg":  "請求頭中auth格式有誤",
        // })
        // c.Abort()
        // return
        //}
        // parts[1]是獲取到的tokenString,我們使用之前定義好的解析JWT的函式來解析它
        //mc, err := ParseToken(parts[1])

        mc, err := ParseToken(authHeader)
        if err != nil {
            //Log("無效的Token", err)
            Fail(c, "無效的token")
            c.Abort()
            return
        }
        //從redis中獲取token資訊
        result, err := config.RedisClient().Get(mc.UserName).Result()
        if err != nil {
            Fail(c, "獲取token出錯")
            c.Abort()
            return
        }
        tokenMap, err := JsonToMap(result)
        if err != nil {
            Fail(c, "獲取token出錯")
            c.Abort()
            return
        }
        if tokenMap["token"] != authHeader {
            Fail(c, "無效的token")
            c.Abort()
            return
        }
        // 將當前請求的username資訊儲存到請求的上下文c上
        c.Set("username", mc.UserName)
        config.SetVal("username", mc.UserName)
        c.Next() // 後續的處理函式可以用過c.Get("username")來獲取當前請求的使用者資訊
    }

獲取上下文,當前使用者GetVal

//獲取使用者資訊
func UserInfo() en.UserInfo {
    val := config.GetVal("username")
    if val != "" {
        user := mapper.QueryUserByPhoneNumber(val)
        return user
    }
    return en.UserInfo{}
}
本作品採用《CC 協議》,轉載必須註明作者和本文連結

相關文章