Gin 框架 JWT 登录认证超详细实战教程(原理 + 代码 + 拦截器)
·
🏷️ 标签:Gin Go JWT 登录认证 Token 中间件 后端开发 📝 适用人群:Go 初学者、Gin 开发者、前后端分离、课程实训、CSDN 发布 💡 亮点:企业级标准方案,通俗易懂、完整可运行、包含登录颁发 Token、接口鉴权、中间件拦截、Token 过期处理,直接用于项目。
一、前言
在前后端分离项目中,JWT(JSON Web Token) 是目前最主流、最通用的登录认证方案。 相比传统 Session,JWT 无需存储在服务器、支持跨域、适合分布式部署,是现代 Web 开发必备技能。
本文带你从零彻底学会:
- JWT 原理与结构
- Gin 集成 JWT 库
- 登录接口 → 生成并返回 Token
- JWT 认证中间件 → 拦截未登录请求
- Token 过期、无效、伪造异常处理
- 实战可用的完整代码
二、什么是 JWT?
2.1 JWT 是什么
JWT = JSON Web Token 一段加密后的字符串,用于在网络应用中声明身份。
特点:
- 服务端不存储会话(无状态)
- 自带用户信息,加密安全
- 支持跨域、分布式、微服务
- 前后端分离标配
2.2 JWT 组成结构
一段 Token 分为三部分:
- Header(头部):加密算法
- Payload(负载):存放用户 ID、用户名、过期时间
- Signature(签名):防篡改
最终长成这样:
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VySWQiOjEsInVzZXJuYW1lIjoiYWRtaW4iLCJleHAiOjE3MzAwMDAwMDB9.xxxxxx
2.3 JWT 认证流程
- 用户登录 → 账号密码正确
- 服务端生成 JWT Token → 返回给前端
- 前端存储 Token(localStorage)
- 后续请求在请求头携带:
Authorization: Bearer Token - 服务端验证 Token 有效 → 放行请求
三、环境准备
3.1 安装 JWT 依赖
go get github.com/golang-jwt/jwt/v5
3.2 基础项目结构
项目/
├── main.go # 主入口
├── utils/
│ └── jwt.go # JWT工具类
└── middleware/
└── jwt_auth.go # JWT认证中间件
四、编写 JWT 工具类(核心)
创建 utils/jwt.go,用于生成 Token 和 解析 Token
package utils
import (
"errors"
"time"
"github.com/golang-jwt/jwt/v5"
)
// 密钥(一定要自己改!)
var jwtKey = []byte("my_secret_key_123456789")
// 自定义Claims(存放要加密的用户信息)
type MyClaims struct {
UserId int `json:"userId"`
Username string `json:"username"`
jwt.RegisteredClaims
}
// 生成Token
func GenerateToken(userId int, username string) (string, error) {
// 1. 创建自定义声明
claims := MyClaims{
UserId: userId,
Username: username,
RegisteredClaims: jwt.RegisteredClaims{
ExpiresAt: jwt.NewNumericDate(time.Now().Add(24 * time.Hour)), // 过期时间24小时
IssuedAt: jwt.NewNumericDate(time.Now()), // 签发时间
},
}
// 2. 使用HS256加密生成token
token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
// 3. 签名
return token.SignedString(jwtKey)
}
// 解析Token
func ParseToken(tokenString string) (*MyClaims, error) {
// 解析token
token, err := jwt.ParseWithClaims(tokenString, &MyClaims{}, func(token *jwt.Token) (interface{}, error) {
return jwtKey, nil
})
if err != nil {
return nil, err
}
// 校验token
if claims, ok := token.Claims.(*MyClaims); ok && token.Valid {
return claims, nil
}
return nil, errors.New("无效的token")
}
五、编写 JWT 认证中间件
创建 middleware/jwt_auth.go,用于拦截未登录请求
package middleware
import (
"strings"
"github.com/gin-gonic/gin"
"your-project/utils"
)
// JWT认证中间件
func JWTAuthMiddleware() gin.HandlerFunc {
return func(c *gin.Context) {
// 1. 获取请求头Authorization
authHeader := c.GetHeader("Authorization")
if authHeader == "" {
c.JSON(401, gin.H{"code": 401, "msg": "未携带Token,拒绝访问"})
c.Abort()
return
}
// 2. 按格式 Bearer token 切割
parts := strings.SplitN(authHeader, " ", 2)
if !(len(parts) == 2 && parts[0] == "Bearer") {
c.JSON(401, gin.H{"code": 401, "msg": "Token格式错误"})
c.Abort()
return
}
// 3. 解析Token
claims, err := utils.ParseToken(parts[1])
if err != nil {
c.JSON(401, gin.H{"code": 401, "msg": "Token无效或已过期"})
c.Abort()
return
}
// 4. 将用户信息存入上下文,后续接口可直接使用
c.Set("userId", claims.UserId)
c.Set("username", claims.Username)
// 5. 放行
c.Next()
}
}
六、主程序:登录接口 + 测试接口
main.go
package main
import (
"github.com/gin-gonic/gin"
"your-project/middleware"
"your-project/utils"
)
func main() {
r := gin.Default()
// 公共路由(无需登录)
r.POST("/login", func(c *gin.Context) {
// 1. 获取前端传的账号密码
username := c.PostForm("username")
password := c.PostForm("password")
// 2. 模拟校验(真实项目查数据库)
if username == "admin" && password == "123456" {
// 3. 生成Token
token, _ := utils.GenerateToken(1, username)
c.JSON(200, gin.H{
"code": 200,
"msg": "登录成功",
"token": token,
})
return
}
c.JSON(200, gin.H{"code": 400, "msg": "账号或密码错误"})
})
// 需要登录认证的路由组
authGroup := r.Group("/api")
authGroup.Use(middleware.JWTAuthMiddleware())
{
// 获取用户信息
authGroup.GET("/user/info", func(c *gin.Context) {
userId, _ := c.Get("userId")
username, _ := c.Get("username")
c.JSON(200, gin.H{
"userId": userId,
"username": username,
})
})
}
r.Run(":8080")
}
七、接口测试
1. 登录接口(获取 Token)
POST http://localhost:8080/login
参数:
username=admin
password=123456
返回:
{
"code": 200,
"msg": "登录成功",
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
}
2. 带 Token 请求需要登录的接口
请求头:
Authorization: Bearer 你的Token
接口地址:
GET http://localhost:8080/api/user/info
返回用户信息,说明认证成功!
八、JWT 常见异常说明
| 异常场景 | 提示 |
|---|---|
| 未传 Token | 未携带 Token,拒绝访问 |
| 格式错误 | Token 格式错误 |
| 过期 / 伪造 | Token 无效或已过期 |
| 正确 | 成功获取用户信息 |
九、JWT 优点总结
- 无状态:服务端不用存储 Session,减轻压力
- 跨域完美支持:不受 Cookie 跨域限制
- 分布式友好:多台服务器共享认证
- 自包含:自带用户信息,无需查库
- 安全:签名防篡改,加密传输
十、企业级注意事项
jwtKey密钥必须复杂、不能泄露- Token 过期时间不宜过长(2 小时~1 天)
- 敏感信息不要放在 Payload(可解码)
- 生产环境建议使用 HTTPS
- 可实现 RefreshToken 机制,自动续期
十一、总结
- JWT 是前后端分离标准登录方案
- 流程:登录生成 Token → 请求携带 Token → 中间件验证
- 核心三部分:工具类(生成 / 解析)、认证中间件、登录接口
- Gin 中使用
github.com/golang-jwt/jwt/v5 - 中间件拦截未登录请求,安全可靠
- 无状态、跨域、分布式支持,企业必用
版权声明
本文为原创 Gin JWT 登录认证 实战教程,代码完整可直接运行,适合 CSDN 发布、课程实训、作业、面试复习,禁止未经授权转载抄袭。
openEuler 是由开放原子开源基金会孵化的全场景开源操作系统项目,面向数字基础设施四大核心场景(服务器、云计算、边缘计算、嵌入式),全面支持 ARM、x86、RISC-V、loongArch、PowerPC、SW-64 等多样性计算架构
更多推荐


所有评论(0)