JWT 入门笔记(Go Web 项目必备认证方案)
·
一、什么是 JWT
JWT(JSON Web Token)是一种轻量级认证方案,用于:
- 前后端分离的用户认证
- 传递安全信息
特点:
- 无状态(服务端不存储 Session)
- 可跨域、可跨服务
- 支持加密或签名
JWT 本质上是一个字符串,由三部分组成:
header.payload.signature
二、JWT 三部分详解
1. Header(头部)
- 声明类型和加密算法
- 通常是:
{
"alg": "HS256",
"typ": "JWT"
}
2. Payload(负载)
- 存储实际信息(Claims)
- 比如用户 ID、过期时间等
{
"userId": 1001,
"username": "zjl",
"exp": 1684089600
}
exp表示过期时间(Unix 时间戳)
3. Signature(签名)
签名算法:
HMACSHA256(
base64UrlEncode(header) + "." + base64UrlEncode(payload),
secret
)
作用:
防篡改,确保 JWT 没有被伪造
三、JWT 优势
- 无需服务器存储 Session
- 支持跨域和微服务
- 适合前后端分离场景
四、Go 中使用 JWT
Go 常用库:
github.com/golang-jwt/jwt/v4
安装:
go get github.com/golang-jwt/jwt/v4
五、生成 JWT
示例代码:
package main
import (
"fmt"
"time"
"github.com/golang-jwt/jwt/v4"
)
func main() {
// 声明 payload
claims := jwt.MapClaims{
"userId": 1001,
"username": "zjl",
"exp": time.Now().Add(time.Hour * 1).Unix(),
}
// 创建 token
token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
// 使用 secret 签名
secret := []byte("mysecret")
tokenString, err := token.SignedString(secret)
if err != nil {
panic(err)
}
fmt.Println("生成的 JWT:", tokenString)
}
六、解析 JWT
package main
import (
"fmt"
"github.com/golang-jwt/jwt/v4"
)
func main() {
tokenString := "上一步生成的 token"
secret := []byte("mysecret")
// 解析 token
token, err := jwt.Parse(tokenString, func(token *jwt.Token) (interface{}, error) {
return secret, nil
})
if err != nil {
panic(err)
}
// 校验通过
if claims, ok := token.Claims.(jwt.MapClaims); ok && token.Valid {
fmt.Println("userId:", claims["userId"])
fmt.Println("username:", claims["username"])
} else {
fmt.Println("Token 无效")
}
}
七、JWT 在 Gin 中使用
1. 登录接口生成 token
r.POST("/login", func(c *gin.Context) {
// 假设校验用户名密码通过
token := jwt.NewWithClaims(jwt.SigningMethodHS256, jwt.MapClaims{
"userId": 1001,
"exp": time.Now().Add(time.Hour * 1).Unix(),
})
tokenString, _ := token.SignedString([]byte("mysecret"))
c.JSON(200, gin.H{
"token": tokenString,
})
})
2. 中间件校验 JWT
func JWTMiddleware() gin.HandlerFunc {
return func(c *gin.Context) {
tokenString := c.GetHeader("Authorization")
if tokenString == "" {
c.JSON(401, gin.H{"msg": "缺少 token"})
c.Abort()
return
}
token, err := jwt.Parse(tokenString, func(token *jwt.Token) (interface{}, error) {
return []byte("mysecret"), nil
})
if err != nil || !token.Valid {
c.JSON(401, gin.H{"msg": "token 无效"})
c.Abort()
return
}
c.Next()
}
}
使用:
auth := r.Group("/auth")
auth.Use(JWTMiddleware())
auth.GET("/profile", func(c *gin.Context) {
c.JSON(200, gin.H{"msg": "这是受保护的接口"})
})
八、JWT 注意事项
- Secret 必须保密
- token 应该设置过期时间
- 不要在 payload 放敏感信息(密码等)
- 前端使用 Authorization: Bearer token 传递
九、总结
JWT 核心概念:
- Header:声明算法和类型
- Payload:存放用户信息和过期时间
- Signature:签名,防篡改
在 Go Web 开发中:
- 登录生成 JWT
- 前端存储 token
- 请求带 token
- 后端中间件验证 token
这样就完成了无状态认证。
更多推荐



所有评论(0)