第一步安装jwt
go get github.com/dgrijalva/jwt-go
第二步编写jwt.go 中间件文件
package middleware
import (
"strings"
"time"
"webgin/utils"
"webgin/utils/errmsg"
"webgin/utils/msgjson"
"github.com/dgrijalva/jwt-go"
"github.com/gin-gonic/gin"
)
/*
这里的utils.JwtKey 我用uuid插件生成的e9a62e0d-d520-465f-8188-c3e7b13977bd
*/
var JwtKey = []byte(utils.JwtKey)
// MyClaims 结构表示 JWT 中的声明
type MyClaims struct {
Username string `json:"username"`
jwt.StandardClaims
}
// SetToken 生成 JWT Token 并返回
func SetToken(username string) (string, int) {
// 设置 Token 过期时间为 24 小时
expireTime := time.Now().Add(time.Hour * 24).Unix()
// 创建自定义声明结构
claims := MyClaims{
username,
jwt.StandardClaims{
ExpiresAt: expireTime, // 过期时间
Issuer: "xwya",
},
}
// 使用 HS256 签名算法创建 Token
token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
// 签名 Token 并返回
tokenString, err := token.SignedString(JwtKey)
if err != nil {
return "", errmsg.Error
}
return tokenString, errmsg.Success
}
// CheckToken 验证 JWT Token 并返回声明
func CheckToken(tokenString string) *MyClaims {
// 解析 Token 并验证签名
token, err := jwt.ParseWithClaims(tokenString, &MyClaims{}, func(token *jwt.Token) (interface{}, error) {
return JwtKey, nil
})
// token.Valid 判断token是否是有效值
// 处理解析和验证错误
if err != nil || err == jwt.ErrSignatureInvalid || !token.Valid {
return nil // Token 格式错误
}
// 检查 Token 是否有效并返回声明
claims, _ := token.Claims.(*MyClaims)
return claims
}
// jwt中间件
func JwtToken() gin.HandlerFunc {
return func(c *gin.Context) {
token := c.GetHeader("Authorization")
if token == "" {
msgjson.ErrorMsg(c, errmsg.GetErrMsg(errmsg.Error_TokenExist)) // token 错误
c.Abort()
return
}
// 将 Token 头分成两部分,"Bearer" 和 Token 字符串
checkToken := strings.SplitN(token, " ", 2)
if len(checkToken) != 2 && checkToken[0] != "Bearer" {
msgjson.ErrorMsg(c, errmsg.GetErrMsg(errmsg.Error_TokenMalformed)) // token 格式错误
c.Abort()
return
}
// 验证 Token 并获取声明
key := CheckToken(checkToken[1])
if key == nil {
msgjson.ErrorMsg(c, errmsg.GetErrMsg(errmsg.Error_TokenInvalid)) // token 无效
c.Abort()
return
}
// 检查 Token 是否已过期
if time.Now().Unix() > key.ExpiresAt {
msgjson.ErrorMsg(c, errmsg.GetErrMsg(errmsg.Error_TokenTimeout)) // token 过期
c.Abort()
return
}
// 将声明中的用户名添加到上下文中
c.Set("username", key.Username)
c.Next()
}
}
第三步 加入使用的路由组
package route
import (
con "webgin/api/v1"
"webgin/middleware"
"webgin/utils"
"webgin/utils/validator"
"github.com/gin-gonic/gin"
)
// 初始化路由
func InitRoute() {
gin.SetMode(utils.AppMode)
// 初始化路由
r := gin.Default()
// 初始化翻译器
validator.InitValidate()
r.Use(middleware.InitLogger())
router := r.Group("/api")
// 后台登录接口模块
{
adminLoginRoute := router.Group("/adminlogin")
{
// 后台登录
adminLoginRoute.POST("/login", con.AdminLogin)
// // 后台退出登录
// adminLoginRoute.POST("/logout", con.AdminLogout)
// // 后台获取用户信息
// adminLoginRoute.GET("/getAdminUserInfo", con.GetAdminUserInfo)
// // 后台获取用户列表
}
}
// 后台用户路由模块
{
adminUserRoute := router.Group("/adminuser")
// adminUserRoute.Use(middleware.JwtToken())
{
// 添加后台用户
adminUserRoute.POST("/addAdminUser", con.AddAdminUser)
// 删除后台用户
adminUserRoute.POST("/oddAdminUser", con.OddAdminUser)
// 修改后台用户密码
adminUserRoute.POST("/EditPassword", con.EditAdminUserPassword)
// 修改后台用户权限
adminUserRoute.POST("/EditAdminRole", con.EditAdminUserAuthority)
// 获取后台用户列表
adminUserRoute.GET("/getAdminUserList/:pageNum/:pageSize", con.GetAdminUserList)
// 获取用户信息
adminUserRoute.GET("/getAdminUserInfo/:id", con.GetAdminUserInfo)
}
}
r.Run(utils.Prot)
}
第四步编写登录接口 实现settoken
控制层代码
package controller
import (
"webgin/model"
msgjson "webgin/utils/msgjson"
m "webgin/middleware"
"github.com/gin-gonic/gin"
)
// 登录接口
func AdminLogin(c *gin.Context) {
var userInfo map[string]string
c.BindJSON(&userInfo)
// 查询用户是否存在
res := model.GetAdminUser(userInfo["username"])
if res == "" {
msgjson.ErrorMsg(c, "用户不存在请联系管理员")
return
}
// 去登录
username, err := model.AdminLogin(userInfo["username"], userInfo["password"])
if err != nil || username == "" {
c.Set("err", err.Error())
msgjson.ErrorMsg(c, "用户名或密码错误")
return
}
// 添加token
token, code := m.SetToken(username)
if code == 200 {
msgjson.LoginMsg(c, "登录成功", token)
} else {
msgjson.ErrorMsg(c, "登录失败")
}
}
服务层代码
// 查询用户是否存在
func GetAdminUser(username string) string {
var user AdminUser
db.Select("id").Where(" username = ?", username).First(&user)
if user.ID > 0 {
return errmsg.GetErrMsg(errmsg.Error_UserExist)
}
return ""
}
// 登录接口
func AdminLogin(username, password string) (string, error) {
var user AdminUser
tx := db.Begin()
if err := tx.Model(&AdminUser{}).Where("username = ? and password = ?", username, cryptor.HmacMd5(utils.PassPrefix, password)).First(&user).Error; err != nil {
tx.Rollback()
return "", err
}
if err := tx.Commit().Error; err != nil {
tx.Rollback()
return "", err
}
return user.Username, nil
}