gin+jwt验证,cookie
cookie示范
//设置cookie
//字段名,内容,有效期(秒),生效路径,有效域,仅https,仅HTTP访问Cookie(js无法访问)
c.SetCookie("token", tokenString, 680400, "/", "127.0.0.1", false, true)
//读取cookie
tokenString, _ := c.Cookie("token")
// 如果没有 token 字段,返回 401 错误
if tokenString == "" {
c.JSON(401, gin.H{"error": "未提供身份验证信息"})
c.Abort()
return
}
jwt示范
jwt.go:
package services
import (
"github.com/golang-jwt/jwt/v5"
"github.com/gin-gonic/gin"
"time"
"fmt"
)
// 定义 JWT 签名密钥
var jwtKey = []byte("1sD5e+cF2rNeP7Mt6_k3R7e4y")
// 定义 JWT 签发函数
func GenerateJWT(user string) (string, error) {
// 创建 JWT Claims 对象
token := jwt.NewWithClaims(jwt.SigningMethodHS256, jwt.MapClaims{
//设置超时时间
"exp": time.Now().Add(10080 * time.Minute).Unix(),
"username": "muxiaoliang", //这是存入的用户名
})
// 生成 JWT Token
tokenString, err := token.SignedString(jwtKey)
// 使用密钥进行签名生成字符串 token
if err != nil {
return "", err
}
return tokenString, nil
}
// 定义 JWT 认证中间件函数
func AuthenticateJWT(c *gin.Context) {
// // 获取请求头中的 Authorization 字段
// tokenString := c.GetHeader("Authorization")
//获取cookie中的token字段
tokenString, _ := c.Cookie("token")
// 如果没有 Authorization 字段,返回 401 错误
if tokenString == "" {
c.JSON(401, gin.H{"error": "未提供身份验证信息"})
c.Abort()
return
}
token, err := jwt.Parse(tokenString, func(token *jwt.Token) (interface{}, error) {
//这里的参数就是方法,方法直接返回jwtKey令牌
return jwtKey, nil
})
// 检查token是否有效
if !token.Valid {
c.JSON(401, gin.H{"无效的token": err})
fmt.Println("无效的token",err)
c.Abort()
return
}
if claims, ok := token.Claims.(jwt.MapClaims); ok {
fmt.Println("找到用户:", claims["username"])
// 将解析后的claims存储到上下文中,以便后续处理程序可以访问
//例如返回用户名,权限
c.Set("claims", claims["username"])
} else {
fmt.Println("token解析失败",err)
c.JSON(401, gin.H{"token解析失败": err})
c.Abort()
return
}
c.Next()
}
user.go:
// 文章内容
func User(c *gin.Context) {
// 获取当前请求的HTTP方法
method := c.Request.Method
//如果是post
if method == "POST" {
//登录验证
user := c.PostForm("username")
password := c.PostForm("password")
//这里是验证用户密码逻辑,假如已经验证通过
//调用jwt签发函数并保存到cookie,也可以直接返回json的token让客户端自己处理
tokenString, err := services.GenerateJWT(user)
if err != nil {
c.JSON(400, gin.H{"error": "生成令牌失败"})
return
}
c.SetCookie("token", tokenString, 680400, "/", "127.0.0.1", false, true)
//跳转到后台路由
c.Redirect(302, "/admin")
return
}
//如果是get方法则直接返回页面
c.HTML(200, "user.html", nil)
}
需要验证身份的路由:
//services.AuthenticateJWT是中间函数,controller.Admin是视图函数
//路由会依此执行下面的函数
r.GET("/admin",services.AuthenticateJWT,controller.Admin) //管理员页面,需要验证
验证身份的视图函数:
// 管理员页面
func Admin(c *gin.Context) {
// // 获取上下文传递的内容,例如用户名,权限
// claims := c.MustGet("claims")
c.HTML(200, "admin_index.html",nil)
}