gin + vue3 搭建博客系统 (5)jwt 鉴权

194 阅读1分钟

一、创建token

type CustomClaims struct {  
jwt.StandardClaims  
  
UID uint  
UserName string  
}  
  
func (c CustomClaims) CreateToken(userName string, uid uint) (token string, err error) {  
tokenData := jwt.NewWithClaims(jwt.SigningMethodHS256, CustomClaims{  
StandardClaims: jwt.StandardClaims{  
ExpiresAt: time.Now().Unix() + int64(global.Config.Jwt.JwtTtl),  
Id: strconv.Itoa(int(uid)),  
NotBefore: time.Now().Unix() - 10000,  
},  
UID: uid,  
UserName: userName,  
})  
token, err = tokenData.SignedString([]byte(global.Config.Jwt.Secret))  
if err != nil {  
global.Log.Error("审计token签名错误", zap.String("err", err.Error()))  
}  
return token, err  
}  
  
// ParseToken 解析token  
func ParseToken(tokenStr string) (*jwt.Token, error) {  
token, err := jwt.ParseWithClaims(tokenStr, &CustomClaims{}, func(token *jwt.Token) (interface{}, error) {  
return []byte(global.Config.Jwt.Secret), nil  
},  
)  
return token, err  
}

二、创建gin JWT中间间解析token

func JWTAuth() gin.HandlerFunc {  
return func(c *gin.Context) {  
tokenStr := c.Request.Header.Get("Authorization")  
if tokenStr == "" {  
global.Log.Error("token不能为空")  
response.ValidateErr(c, "token不能为空")  
c.Abort()  
return  
}  
token, err := ParseToken(tokenStr)  
if err != nil {  
global.Log.Error("token 解析错误")  
response.ValidateErr(c, "token 解析错误")  
c.Abort()  
return  
}  
  
claims := token.Claims.(*CustomClaims)  
c.Set("token", tokenStr)  
c.Set("id", claims.UID)  
c.Set("userName", claims.UserName)  
  
}  
}

三、在api/user.go 添加登录和获取用户信息发方法

// Login 登录  
func (u user) Login(c *gin.Context) {  
var form form.LoginReq  
if err := c.ShouldBindJSON(&form); err != nil {  
utils.HandleValidatorError(c, err)  
return  
}  
user, err := service.User.Login(form)  
if err != nil {  
response.BusinessError(c, err.Error())  
}  
token, err := middleware.CreateToken(user.UserName, user.ID)  
if err != nil {  
global.Log.Error("生成token失败")  
response.BusinessError(c, "生成token失败")  
return  
}  
response.Success(c, map[string]string{  
"token": token,  
})  
  
}  
  
// GetUserById 根据id查询用户  
func (u user) GetUserById(c *gin.Context) {  
id := c.Query("id")  
if id == "" {  
global.Log.Error("用户ID不能为空")  
response.ValidateErr(c, "用户ID不能为空")  
return  
}  
uId, err := strconv.Atoi(id)  
if err != nil {  
global.Log.Error("用户ID非法")  
response.ValidateErr(c, "用户ID非法")  
return  
}  
user, err := service.User.GetUserById(uint(uId))  
if err != err {  
response.BusinessError(c, err.Error())  
return  
}  
response.Success(c, user)  
  
}

四、在service/user.go 写登录和获取用户操作数据库的逻辑

func (u user) Login(form form.LoginReq) (user models.User, err error) {  
  
err = global.DB.Where("user_name = ? and password = ?", form.UserName, form.Password).First(&user).Error  
return user, err  
  
}  
  
func (u user) GetUserById(id uint) (models.User, error) {  
var user models.User  
err := global.DB.First(&user, id).Error  
return user, err  
}

五、在route/user.go 注册路由

route.POST("/login", api.User.Login)  
route.Use(middleware.JWTAuth()).GET("userInfo", api.User.GetUserById)

六、启动服务,postman测试

image.png

image.png