保存用户登录状态,一般常用的方式有两种
一、生成token,然后token保存到数据库用户表里面,每次登录的时候,自动更新,容纳后每次用的时候,去取出来校验,这种方式,数据库压力大,而且不是很灵活
二、每次登录生成token,然后token保存到Redis缓存中,每次都去校验,不仅快速,而且,数据库压力也小
1.启动时候,加载Redis项
2、Redis(附带参数文件)
前期准备工作好之后
1、路由,利用路由文件,添加中间件,将所有需要验证token的接口放一起
比如前端要访问的接口是“api/index/index”
package router
import (
"fmt"
"github.com/gin-gonic/gin"
"hexiao/service"
)
func Router() *gin.Engine {
r := gin.Default()
//修改密码
r.POST("api/user/changepwd", service.ChangePwd)
//登录
r.POST("api/user/login", service.Login)
//设置需要登录验证的一些函数
IndexGroup := r.Group("/api/index")
{
//调用中间件
IndexGroup.Use(service.AuthMiddleWare())
IndexGroup.POST("/index", service.IndexInfo)
}
return r
}
中间件控制
//token存入redis部分代码
token := "xxxxxxxxxxxxxx"
ctx := context.Background()
userID := "online_" + fmt.Sprintf("%d", adminuser2.Id)
time2 := time.Duration(viper.GetInt("timeout.RedisOnlineTime")) * time.Hour
err := utils.Red.Set(ctx, userID, token, time2)
if err != nil {
fmt.Println("set err=", err)
}
//取token验证中间件
func AuthMiddleWare() gin.HandlerFunc {
return func(c *gin.Context) {
ctx := context.Background()
userid1 := c.PostForm("user_id")
token := c.PostForm("token")
if token == "" {
c.JSON(200, gin.H{
"code": 300,
"data": "",
"msg": "请携带token!",
})
c.Abort()
return
}
userID := "online_" + userid1
r, err := utils.Red.Get(ctx, userID).Result()
if err != nil {
fmt.Println("err>>>>>>", err)
}
if r != token {
c.JSON(200, gin.H{
"code": 300,
"data": "",
"msg": "登录失效,请重新登录!",
})
c.Abort()
return
}
}
}
具体的token组装方式,自己确定,我这边采用的是固定字符串+user_id的方式,
token可以由body中传,也可以由header中传
效果
无token:
token错误:
token正确