jwt简单使用
安装
go get -u github.com/golang-jwt/jwt/v5
构建token
package main
import (
"fmt"
"time"
"github.com/golang-jwt/jwt/v5"
)
func main() {
// 定义 JWT 签名密钥
mySigningKey := []byte("deb0uuxjjxh32268a2aafb")
// 自定义声明结构体,继承 jwt.RegisteredClaims 以包含标准字段
type MyCustomClaims struct {
Userid int64 `json:"userid"` // 用户 ID
jwt.RegisteredClaims // JWT 标准声明
}
// 创建声明信息
claims := MyCustomClaims{
Userid: 122556222222, // 设置用户 ID
jwt.RegisteredClaims{
ExpiresAt: jwt.NewNumericDate(time.Now().Add(24 * time.Hour)), // 过期时间 24 小时后
Issuer: "alsark", // 签发者
},
}
// 使用 HS256 签名算法创建 JWT 令牌
token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
// 使用密钥对令牌进行签名
ss, _ := token.SignedString(mySigningKey)
// 输出 JWT 令牌
fmt.Println(ss)
}
解析token
package main
import (
"fmt"
"log"
"github.com/golang-jwt/jwt/v5"
)
func main() {
// 定义要解析的 JWT 令牌字符串
tokenString := "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyaWQiOjEyMjU1NjIyMjIyMiwiaXNzIjoiYWxzYXJrIiwiZXhwIjoxNzMxODUxMTgzfQ.n_8gcQIMMgiR4WFq4DjKrYUqIorSBnyfebIMseOc0-0"
// 自定义声明结构体,继承 jwt.RegisteredClaims 以包含标准字段
type MyCustomClaims struct {
Userid int64 `json:"userid"` // 用户 ID
jwt.RegisteredClaims // JWT 标准声明
}
// 解析 JWT 令牌,并验证签名
token, err := jwt.ParseWithClaims(tokenString, &MyCustomClaims{}, func(token *jwt.Token) (interface{}, error) {
// 返回用于签名的密钥
return []byte("deb0uuxjjxh32268a2aafb"), nil
})
// 检查解析是否出错
if err != nil {
log.Fatal(err)
} else if claims, ok := token.Claims.(*MyCustomClaims); ok {
// 成功解析并断言为 MyCustomClaims 结构体,输出用户 ID
fmt.Println(claims.Userid)
} else {
// 解析失败,未知的声明类型
log.Fatal("unknown claims type, cannot proceed")
}
}
与gin结合
定义路由
v1 := r.Group("/v1")
{
v1.GET("/hqtoken", Hqtoken) // 获取 JWT 令牌
}
v2 := r.Group("/v2", Jwtyz()) // 使用 JWT 认证中间件
{
v2.GET("/yztoken", Yztoken) // 需要 JWT 认证的接口
}
JWT 令牌生成
func Hqtoken(c *gin.Context) {
mySigningKey := []byte("Xye8pxrmruM") // 定义 JWT 签名密钥
type MyCustomClaims struct {
Userid string `json:"userid"` // 用户 ID
jwt.RegisteredClaims // 继承标准 JWT 声明
}
userid := "144551222554" // 设置用户 ID
claims := MyCustomClaims{
Userid: userid,
jwt.RegisteredClaims{
ExpiresAt: jwt.NewNumericDate(time.Now().Add(24 * time.Hour)), // 令牌 24 小时后过期
Issuer: "alsark", // 签发者
},
}
token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims) // 使用 HS256 签名算法创建 JWT 令牌
ss, _ := token.SignedString(mySigningKey) // 使用密钥对令牌进行签名
fmt.Println(ss) // 输出 JWT 令牌到终端
c.JSON(200, ss) // 返回 JWT 令牌给客户端
}
JWT 认证中间件
func Jwtyz() gin.HandlerFunc {
return func(c *gin.Context) {
tokenString := c.GetHeader("Authorization") // 从请求头中获取 Authorization
if tokenString == "" {
c.JSON(401, gin.H{"error": "Authorization异常"})
c.Abort()
return
}
type MyCustomClaims struct {
Userid string `json:"userid"`
jwt.RegisteredClaims
}
token, err := jwt.ParseWithClaims(tokenString, &MyCustomClaims{}, func(token *jwt.Token) (interface{}, error) {
return []byte("Xye8pxrmruM"), nil // 返回用于签名的密钥
})
if err != nil {
c.JSON(401, gin.H{"error": "Authorization异常"})
c.Abort()
return
} else if claims, ok := token.Claims.(*MyCustomClaims); ok {
c.Set("userid", claims.Userid) // 解析成功,存入上下文
} else {
c.JSON(401, gin.H{"error": "Authorization异常"})
c.Abort()
return
}
c.Next() // 继续处理请求
}
}
完整代码
package main
import (
"fmt"
"time"
"github.com/gin-gonic/gin"
"github.com/golang-jwt/jwt/v5"
)
func main() {
r := gin.Default()
// 定义路由组 v1,不需要 JWT 认证
v1 := r.Group("/v1")
{
v1.GET("/hqtoken", Hqtoken) // 获取 JWT 令牌的接口
}
// 定义路由组 v2,使用 JWT 认证中间件
v2 := r.Group("/v2", Jwtyz())
{
v2.GET("/yztoken", Yztoken) // 需要 JWT 认证的接口
}
r.Run() // 监听并在 0.0.0.0:8080 上启动服务
}
// Hqtoken 生成 JWT 令牌并返回
func Hqtoken(c *gin.Context) {
// 定义 JWT 签名密钥
mySigningKey := []byte("Xye8pxrmruM")
// 定义自定义声明结构体
type MyCustomClaims struct {
Userid string `json:"userid"` // 用户 ID
jwt.RegisteredClaims // 继承标准 JWT 声明
}
// 设置用户 ID
userid := "144551222554"
// 创建 JWT 声明
claims := MyCustomClaims{
Userid: userid,
jwt.RegisteredClaims{
ExpiresAt: jwt.NewNumericDate(time.Now().Add(24 * time.Hour)), // 令牌 24 小时后过期
Issuer: "alsark", // 签发者
},
}
// 使用 HS256 签名算法创建 JWT 令牌
token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
// 使用密钥对令牌进行签名
ss, _ := token.SignedString(mySigningKey)
// 输出 JWT 令牌到终端
fmt.Println(ss)
// 返回 JWT 令牌给客户端
c.JSON(200, ss)
}
// Yztoken 需要 JWT 认证的接口
func Yztoken(c *gin.Context) {
// 获取中间件存储的用户 ID
userid, _ := c.Get("userid")
// 打印用户 ID
fmt.Println(userid)
}
// Jwtyz JWT 认证中间件
func Jwtyz() gin.HandlerFunc {
return func(c *gin.Context) {
// 从请求头中获取 Authorization 字段
tokenString := c.GetHeader("Authorization")
if tokenString == "" {
// 若请求头中无 Authorization,则返回 401
c.JSON(401, gin.H{"error": "Authorization异常"})
c.Abort()
return
}
// 定义自定义声明结构体
type MyCustomClaims struct {
Userid string `json:"userid"` // 用户 ID
jwt.RegisteredClaims // 继承标准 JWT 声明
}
// 解析 JWT 令牌,并验证签名
token, err := jwt.ParseWithClaims(tokenString, &MyCustomClaims{}, func(token *jwt.Token) (interface{}, error) {
// 返回用于签名的密钥
return []byte("Xye8pxrmruM"), nil
})
// 检查解析是否出错
if err != nil {
c.JSON(401, gin.H{"error": "Authorization异常"})
c.Abort()
return
} else if claims, ok := token.Claims.(*MyCustomClaims); ok {
// 成功解析并断言为 MyCustomClaims 结构体,将用户 ID 存入上下文
c.Set("userid", claims.Userid)
} else {
// 解析失败,未知的声明类型
c.JSON(401, gin.H{"error": "Authorization异常"})
c.Abort()
return
}
// 继续处理请求
c.Next()
}
}
gitee代码示例
https://gitee.com/alsark/gin-combined-with-jwt.githttps://gitee.com/alsark/gin-combined-with-jwt.git