素材巴巴 > 程序开发 >

Gin通过jwt方式实现登录验证基本示例

程序开发 2023-09-03 23:24:57

本文使用Go Gin框架搭建的webserver示例,其中使用jwt进行登录验证,至于cookies session jwt token的区别,优缺点不再本位讨论范围内。

简单总结:使用jwt更方便,具有一定程度安全性,

具体使用Gin搭建webserver提供API服务部分就不赘述了, 可以参考其他博客介绍。完整代码在这里,

代码结构
在这里插入图片描述

1 定义jwt格式部分所需信息和Gin middleware

在标准的Claims信息之外添加一些自定义信息

// 载荷,可添加自己需要的一些信息
 type CustomClaims struct {UserId   int64  `json:"userId"`UserName string `json:"userName"`RoleId   string `json:"roleId"`jwt.StandardClaims
 }
 

类似于java中过滤器

func JWTAuth() gin.HandlerFunc {return func(c *gin.Context) {//过滤是否验证token, login结构直接放行,这里为了简单起见,直接判断路径中是否带login,携带login直接放行if strings.Contains(c.Request.RequestURI, "login") {return}token := c.Request.Header.Get("token")if token == "" {c.JSON(http.StatusOK, gin.H{"status": -1,"msg":    "请求未携带token,无权限访问",})c.Abort()return}klog.Infof("gotten token:%s", token)j := NewJWT()// parse token, get the user and role infoclaims, err := j.ParseToken(token)if err != nil {if err == util.TokenExpired {c.JSON(http.StatusOK, gin.H{"status": -1,"msg":    "授权已过期",})c.Abort()return}c.JSON(http.StatusOK, gin.H{"status": -1,"msg":    err.Error(),})c.Abort()return}// 继续交由下一个路由处理,并将解析出的信息传递下去c.Set(util.Gin_Context_Key, claims)}
 }
 

2 配置路由

/login接口不需要验证登录, 其他接口需要验证登录的token

func ConfigRouter(router *gin.Engine) {userController := mycontroller.NewUserController()//配置middlewarerouter.Use(myjwt.JWTAuth())router.POST("/login", userController.Login)router.GET("/users", userController.GetAllUsers)router.GET("/usersfind", userController.FindUsers)router.GET("/users/:userId", userController.GetOneUser)router.PUT("/users", userController.CreateOneUser)router.POST("/users/:userId", userController.UpdateOneUser)router.DELETE("/users/:userId", userController.DeleteOneUser)
 }
 

3 生成与解析token

生成token

func generateToken(c *gin.Context, user mydomain.User, roleId string, expiredTimeByMinute int64) {j := &myjwt.JWT{[]byte(util.SignKey),}claims := myjwt.CustomClaims{user.UserId,user.UserName,roleId,jwtgo.StandardClaims{NotBefore: int64(time.Now().Unix() - 1000),                   // 签名生效时间ExpiresAt: int64(time.Now().Unix() + expiredTimeByMinute*60), // 过期时间 一小时Issuer:    "ginjwtdemo",                                      //签名的发行者},}token, err := j.CreateToken(claims)if err != nil {c.JSON(http.StatusOK, gin.H{"status": -1,"msg":    err.Error(),})return}data := mydomain.LoginResp{Token: token,}c.JSON(http.StatusOK, gin.H{"status": 0,"msg":    "登录成功!","data":   data,})return
 }
 

解析token

func (j *JWT) ParseToken(tokenString string) (*CustomClaims, error) {token, err := jwt.ParseWithClaims(tokenString, &CustomClaims{}, func(token *jwt.Token) (interface{}, error) {return j.SigningKey, nil})if err != nil {if ve, ok := err.(*jwt.ValidationError); ok {if ve.Errors&jwt.ValidationErrorMalformed != 0 {return nil, util.TokenMalformed} else if ve.Errors&jwt.ValidationErrorExpired != 0 {// Token is expiredreturn nil, util.TokenExpired} else if ve.Errors&jwt.ValidationErrorNotValidYet != 0 {return nil, util.TokenNotValidYet} else {return nil, util.TokenInvalid}}}if claims, ok := token.Claims.(*CustomClaims); ok && token.Valid {return claims, nil}return nil, util.TokenInvalid
 }
 

4 效果演示

获取token
在这里插入图片描述

在header中添加一个过期api的效果
在这里插入图片描述

在header中没有token访问api的效果
在这里插入图片描述

在header中添加一个当前有效的token访问api的效果
在这里插入图片描述


标签:

上一篇: html浏览器内核及兼容性 下一篇:
素材巴巴 Copyright © 2013-2021 http://www.sucaibaba.com/. Some Rights Reserved. 备案号:备案中。