beego應用做純API后端如何使用jwt實現無狀態權限驗證


jwt是什么,可以百度下其它文章,我原來看到一個講的詳細的,現在找不到了。先簡單介紹下我個人的理解,就是一個token,只不過通過加密解密的手段,能讓這一串字符帶有一些簡單的信息。這樣解密jwt后不用查數據庫,最常用的例子,保存用戶權限,再多層的權限,其實只用一個數字,轉換成二進制,每一位代表一種權限。類似這樣的使用,還有保存session的key,通過該值查session就能獲取更豐富的資料,用來保存用戶狀態也是可以的。

下面介紹下我的一個golang項目中使用beego框架做純API接口使用jwt的方法。

 

首先用到jwt函數的go文件都要引入這個庫

import (
  "github.com/dgrijalva/jwt-go"
)

 
登錄函數中登錄成功把jwt字符串發給客戶端,客戶端需要保存起來比如localStorage中,訪問別的API時加到header里面, 注意這個里面exp是必須要的,生命周期。其他都是根據自己需求添加的鍵值對。。
if passwd == user.Password {

            // 帶權限創建令牌
            claims := make(jwt.MapClaims)
            claims["username"] = username
            if username == "admin" {
                claims["admin"] = "true"
            } else {
                claims["admin"] = "false"
            }
            claims["exp"] = time.Now().Add(time.Hour * 480).Unix() //20天有效期,過期需要重新登錄獲取token
            token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)

            // 使用自定義字符串加密 and get the complete encoded token as a string
            tokenString, err := token.SignedString([]byte("mykey"))
            if err != nil {
                beego.Error("jwt.SignedString:", err)
                this.RetError(errSystem)
                return
            }
            this.Data["json"] = map[string]interface{}{"status": 200, "message": "login success ", "moreinfo": tokenString}
        } else {
            this.Data["json"] = map[string]interface{}{"status": 400, "message": "login failed ", "moreinfo": time.Now().Format("2006-01-02 15:04:05")}
        }


baseControler寫這個函數,別的函數全部調用這個做權限認證
// ParseToken parse JWT token in http header.
func (c *BaseController) ParseToken() (t *jwt.Token, e *ControllerError) {
    authString := c.Ctx.Input.Header("Authorization")
    beego.Debug("AuthString:", authString)

    kv := strings.Split(authString, " ")
    if len(kv) != 2 || kv[0] != "Bearer" {
        beego.Error("AuthString invalid:", authString)
        return nil, errInputData
    }
    tokenString := kv[1]

    // Parse token
    token, err := jwt.Parse(tokenString, func(token *jwt.Token) (interface{}, error) {
        return []byte("mykey"), nil
    })
    if err != nil {
        beego.Error("Parse token:", err)
        if ve, ok := err.(*jwt.ValidationError); ok {
            if ve.Errors&jwt.ValidationErrorMalformed != 0 {
                // That's not even a token
                return nil, errInputData
            } else if ve.Errors&(jwt.ValidationErrorExpired|jwt.ValidationErrorNotValidYet) != 0 {
                // Token is either expired or not active yet
                return nil, errExpired
            } else {
                // Couldn't handle this token
                return nil, errInputData
            }
        } else {
            // Couldn't handle this token
            return nil, errInputData
        }
    }
    if !token.Valid {
        beego.Error("Token invalid:", tokenString)
        return nil, errInputData
    }
    beego.Debug("Token:", token)

    return token, nil
}

 

其他API代碼片段
token, e := this.ParseToken()
    if e != nil {
        this.RetError(e)
        return
    }
    claims, ok := token.Claims.(jwt.MapClaims)
    if !ok {
        this.RetError(errPermission)
        return
    }
var user string = claims["username"].(string)

 



免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM