1. 程式人生 > >golang 如何進行jwt許可權驗證

golang 如何進行jwt許可權驗證

閱讀本文需要有基本的go語法基礎,以及熟悉gin框架
在go裡沒有session物件,而又不想使用cookie的方式來進行許可權驗證的話,可以考慮最近比較火的jwt方式進行驗證。

JWT

jwt的介紹,這篇文章寫的非常明白,可以借鑑一下JWT如何理解
總而言之,客戶端通過在request物件header裡新增token引數,傳送到服務端,服務端再拿出token進行比對。
token的第一次產生是發生在login檢查賬戶存在並且正確之後,為該使用者賦予一塊令牌(加密字串),並將token放入response的header裡,客戶端登陸成功後,從response裡取出token,並在以後的操作request請求,都保持在header裡新增該段令牌,令牌有效期失效後,只有重新login,才能獲取新的令牌。

實現

服務端_token生成並放入response的header

import "github.com/fwhezfwhez/jwt"
func Login(c *gin.Context){
    ...(驗證身份正確)
    //獲取token管理物件
    token := jwt.GetToken()
    //新增令牌關鍵資訊
    token.AddPayLoad("userName", user.UserName).AddPayLoad("role", "admin").AddHeader("typ", "JWT").AddHeader("alg", "HS256")
    //新增令牌期限
exp:=time.Now().Add(1*time.Hour) token.AddPayLoad("exp", strconv.FormatInt(exp.Unix(), 10)) //獲取令牌,並新增進reponse的header裡 jwts, _, erre := token.JwtGenerator(consts.Secret) if erre != nil { fmt.Println("token生成出錯") return } fmt.Println("生成的jwt是:", jwts) c.Writer.Header().Add("x-auth-token"
, jwts) ... }

客戶端_傳送login請求

var Token string
func main(){
        ...
        var content = fmt.Sprintf("userName=admin&password=123456")
        t1 := time.Now()
        resp, err := http.Post(host+"v1/POST/user/login", "application/x-www-form-urlencoded", strings.NewReader(content))
        Token =resp.Header.Get("x-auth-token")
        t2 := time.Now()
        fmt.Println(t2.Sub(t1))
        if err != nil {
            panic(err)
        }
        helpRead(resp)
        ...
        }

客戶端_請求其他功能獲取列表

        ...
        t1 := time.Now()

        //resp, err := http.Get(host + "v1/GET/mediums/list")
        client := &http.Client{}
        req, err := http.NewRequest("GET", "http://localhost:8087/v1/GET/mediums/list",nil)
        req.Header.Add("x-auth-token", Token)
        resp, err := client.Do(req)
        t2 := time.Now()
        fmt.Println(t2.Sub(t1))
        if err != nil {
            panic(err)
        }
        helpRead(resp)
        ...

服務端_令牌校驗

func main(){
    ...
    router := gin.Default()
    //Login不需要令牌驗證,所以寫中介軟體前面
    router.POST(consts.LoginURL, userControl.Login)

    router.Use(Validate())
    //後續的監聽都需要通過Validate()的驗證
    router.GET(consts.GetMediumsURL, mediumControl.GetMediums)
    router.....
    ...
    }
func Validate()gin.HandleFunc{
return func(c *gin.Context) {
        if JWTToken := c.Request.Header.Get("x-auth-token");JWTToken!=""{
            token :=jwt.GetToken()
            legal,err:=token.IsLegal(JWTToken,consts.Secret)
            if err!=nil{
                fmt.Println(err)
                c.Abort()
                c.JSON(200,consts.ResponseTokenValidateError)
                return
            }
            if !legal{
                c.Abort()
                c.JSON(200,consts.ResponseTokenValidateWrong)
                return
            }
            c.Next()
        }else{
            c.JSON(200, consts.ResponseTokenNotFound)
            c.Abort()
            return
        }
    }
}