GO语言gin框架实战-02-Jwt和登录认证

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 != "liubei@161" {
        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 测试登录接口

image.png

登录成功获取到token。

4.2 postman设置Cookies

image.png

注意:Crow这个 key的名字是刚才我们在代码里边指定的

4.3 其他接口调用身份验证测试

  • 成功的情况

我们可以看到Headers里多了我们刚才添加的Cookie,是我们刚才添加的Crow

image.png
  • 验证失败的情况

我们把刚才的Cookie改成错的,然后再测试:

image.png

版权声明:
作者:Alex
链接:https://www.techfm.club/p/58118.html
来源:TechFM
文章版权归作者所有,未经允许请勿转载。

THE END
分享
二维码
< <上一篇
下一篇>>