gin框架中jwt实战之用户登录返回token

发布时间 2023-04-14 22:28:09作者: yangphp

流程:

1main.go 中定义路由login 调用 user.Login方法

2user.login方法验证用户名,和密码,并生成token返回

3main.go中定义getUserInfo路由,调用 user.GetUserInfo的方法

4getUserinfo中调用中间件对用户传过来的token进行验证

5、验证通过后返回用户信息

文件:

main.go 路由定义

controller/user/user.go 定义用户登录和获取用户信息的方法

common/jwt/jwt.go 定义生成token的方法

middleware/jwt/auth.go 定义token验证的中间件

 

6、调用:

(1)http://127.0.0.1:8080/login  输入 用户名,密码 进行登录

(2)http://127.0.0.1:8080/getUserinfo 输入token返回用户信息

代码如下:

 

main.go

 

import (
    "github.com/gin-gonic/gin"
    "learn/controller/user"
    MiddlewareJwt "learn/middleware/jwt"
)

func main() {
    router := gin.Default()
    //定义路由
    router.POST("login", user.Login)
    //使用中间件
    router.Use(MiddlewareJwt.JwtAuth)
    {
        router.POST("getUserInfo", user.GetUserInfo)
    }
    router.Run()
}

 

 

controller/user/user.go

import (
    "github.com/gin-gonic/gin"
    Jwt "learn/common/jwt"
    "net/http"
)

// 定义结构体,接收表单提交的数据
type User struct {
    Name     string `form:"name" binding:"required"`
    Password string `form:"password" binding:"required"`
}

func Login(c *gin.Context) {
    var u User
    err := c.ShouldBind(&u)
    if err != nil {
        c.JSON(http.StatusOK, gin.H{"code": 500, "msg": err.Error()})
        return
    }
    if u.Password != "123456" || u.Name != "lampol" {
        c.JSON(http.StatusOK, gin.H{"code": 500, "msg": "用户名或密码错误"})
        return
    }
    //登录成功,获取token返回给前端
    token := Jwt.GetToken(u.Name)
    c.JSON(http.StatusOK, gin.H{
        "code":  400,
        "msg":   "login success",
        "token": token,
    })
    return
}

func GetUserInfo(c *gin.Context) {

    claims, _ := c.Get("cliaims")
    //判断token
    c.JSON(http.StatusOK, gin.H{
        "code":   400,
        "msg":    "GetUserInfo Success",
        "claims": claims,
    })
}

common/jwt/jwt.go

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

type UserClaims struct {
    jwt.StandardClaims //嵌套
    UserName           string
}

var JWTKEY = []byte("lampol123456")

// 获取token
func GetToken(name string) string {
    //payload
    claims := UserClaims{
        UserName: name,
        StandardClaims: jwt.StandardClaims{
            ExpiresAt: time.Now().Add(120 * time.Second).Unix(), //过期时间
            IssuedAt:  time.Now().Unix(),                        //签发时间
            //Subject:   "user token",
        },
    }
    token := jwt.NewWithClaims(jwt.SigningMethodHS256, &claims)
    tokenString, err := token.SignedString(JWTKEY)
    if err != nil {

        log.Fatal(err.Error())
    }
    return tokenString
}

middleware/jwt/auth.go

import (
    "github.com/dgrijalva/jwt-go"
    "github.com/gin-gonic/gin"
    Jwt "learn/common/jwt"
    "net/http"
)

// 验证 token
func JwtAuth(c *gin.Context) {
    token := c.Request.Header.Get("token")
    if token == "" {
        c.JSON(http.StatusOK, gin.H{"code": 500, "msg": "no token"})
        c.Abort() //终止
        return
    }

    claims := Jwt.UserClaims{}
    _, err := jwt.ParseWithClaims(token, &claims, func(t *jwt.Token) (interface{}, error) {
        return Jwt.JWTKEY, nil
    })
    //验证失败
    if err != nil {
        ve, _ := err.(*jwt.ValidationError)
        if ve.Errors == jwt.ValidationErrorExpired {
            c.JSON(http.StatusOK, gin.H{"code": 404, "msg": "token expired"})
        } else {
            c.JSON(http.StatusOK, gin.H{"code": 405, "msg": "token invalid"})
        }
        c.Abort() //终止
        return
    }

    c.Set("cliaims", claims) //传递参数
}

 

完结