天天看點

GO語言gin架構實戰-02-Jwt和登入認證1. 相關函數2. router對其調用3. 其他接口身份驗證4. postman 測試

文章目錄

  • 1. 相關函數
  • 2. router對其調用
  • 3. 其他接口身份驗證
  • 4. postman 測試
    • 4.1 測試登入接口
    • 4.2 postman設定Cookies
    • 4.3 其他接口調用身份驗證測試

1. 相關函數

建立如下函數:
  • 登入函數:登入接口調用該函數
  • 身份驗證:其他函數調用該函數,用token判斷身份是否合法
  • 重新整理token:登入接口調用該函數,如果token驗證通過則發放新token
  • 驗證token:需要驗證身份的服務調用該函數判斷token是否合法
  • 生成token: 其他函數調用該函數,用以生成新token
package router

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

type LoginInfo struct {
	UserName string  `json:"user_name"`
	Password string `json:"password"`
}


type JWTClaims struct { // token裡面添加使用者資訊,驗證token後可能會用到使用者資訊
	jwt.StandardClaims
	UserID      int      `json:"user_id"`
	Password    string   `json:"password"`
	Username    string   `json:"username"`
	FullName    string   `json:"full_name"`
	Permissions []string `json:"permissions"`
}

var (
	Secret     = "LiuBei" // 加鹽
	ExpireTime = 3600*24        // token有效期
)

//登入
func Login(c *gin.Context) {

	var loginRequest LoginInfo
	err := c.Bind(&loginRequest)
	if err != nil {
		c.JSON(400,err.Error())
		return
	}
	//模拟使用者認證
	if loginRequest.UserName != "liuBei" || loginRequest.Password != "[email protected]" {
		c.JSON(401,gin.H{"err":"賬号或密碼錯誤"})
		return
	}

	claims := &JWTClaims{
		UserID:      1,
		Username:    loginRequest.UserName,
		Password:    loginRequest.Password,
		FullName:    loginRequest.UserName,
		Permissions: []string{},
	}
	claims.IssuedAt = time.Now().Unix()
	claims.ExpiresAt = time.Now().Add(time.Second * time.Duration(ExpireTime)).Unix()
	signedToken,err:=getToken(claims)

	if err!=nil {
		c.JSON(400,err.Error())
		return
	}
	//fmt.Printf(signedToken)
	c.JSON(200, gin.H{"token": signedToken})
}


//身份驗證

func Verify(c *gin.Context)(result bool,userName string,err error) {
	strToken,err := c.Cookie("Crow")
	if strToken == ""{
		result = false
		return result,"",nil
	}
	claim,err := verifyAction(strToken)
	if err != nil {
		result = false
		return result,"",nil
	}
	result = true
	userName = claim.Username
	return result,userName,nil
}

//重新整理token
func Refresh(c *gin.Context) {
	strToken,err := c.Cookie("Crow")
	claims,err := verifyAction(strToken)
	if err != nil {
		c.JSON(400,gin.H{"err":err.Error()})
		return
	}
	claims.ExpiresAt = time.Now().Unix() + (claims.ExpiresAt - claims.IssuedAt)
	signedToken,err:=getToken(claims)
	if err!=nil{
		c.JSON(400,gin.H{"err":err.Error()})
		return
	}
	c.JSON(200,gin.H{"data": signedToken })
}

//驗證token是否存在,存在則擷取資訊
func verifyAction(strToken string) (claims *JWTClaims,err error) {
	token, err := jwt.ParseWithClaims(strToken, &JWTClaims{}, func(token *jwt.Token) (interface{}, error) {
		return []byte(Secret), nil
	})
	if err != nil {
		return nil, err
	}
	claims, ok := token.Claims.(*JWTClaims)
	if !ok {
		return nil, err
	}
	if err := token.Claims.Valid(); err != nil {
		return nil, err
	}
	return claims, nil
}

//生成token
func getToken(claims *JWTClaims)(signedToken string,err error){
	token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
	signedToken, err = token.SignedString([]byte(Secret))
	if err != nil {
		return "",err
	}
	return signedToken,nil
}


           

2. router對其調用

loginGroup := r.Group("/api/v1/login")
	{
		loginGroup.POST("/", Login) //登入伺服器
		loginGroup.POST("/refresh", Refresh) //生成新token
	}
           

3. 其他接口身份驗證

以上一章k8s服務的 查詢deployment接口為例,開頭添加如下内容:

func GetDeployment(c *gin.Context)  {
	//身份認證
	checkUser,_,err := Verify(c) //第二個值是使用者名,這裡沒有使用
	if err != nil{
		c.JSON(400,gin.H{"err":err.Error()})
		return
	}
	if checkUser == false {
		c.JSON(400,gin.H{"err":"身份認證失敗"})
		return
	}

	//查詢開始
	……
}
           

4. postman 測試

4.1 測試登入接口

GO語言gin架構實戰-02-Jwt和登入認證1. 相關函數2. router對其調用3. 其他接口身份驗證4. postman 測試
登入成功擷取到token。

4.2 postman設定Cookies

GO語言gin架構實戰-02-Jwt和登入認證1. 相關函數2. router對其調用3. 其他接口身份驗證4. postman 測試
注意:

Crow

這個 key的名字是剛才我們在代碼裡邊指定的

4.3 其他接口調用身份驗證測試

  • 成功的情況
我們可以看到Headers裡多了我們剛才添加的Cookie,是我們剛才添加的Crow
GO語言gin架構實戰-02-Jwt和登入認證1. 相關函數2. router對其調用3. 其他接口身份驗證4. postman 測試
  • 驗證失敗的情況
我們把剛才的Cookie改成錯的,然後再測試:
GO語言gin架構實戰-02-Jwt和登入認證1. 相關函數2. router對其調用3. 其他接口身份驗證4. postman 測試
GO語言gin架構實戰-02-Jwt和登入認證1. 相關函數2. router對其調用3. 其他接口身份驗證4. postman 測試