网站首页 > 文章精选 正文
JWT(JSON Web Token) 是一种用于在客户端和服务器之间安全传递信息的开放标准(RFC 7519)。在 Go 语言中,可以通过使用第三方库(如 github.com/golang-jwt/jwt)轻松实现 JWT 的生成和验证。
以下是 Go 语言中使用 JWT 的详细教程,包含代码示例和说明。
1. 安装依赖
首先,安装 Go 的 JWT 库:
go get -u github.com/golang-jwt/jwt/v5
2. 生成 JWT
步骤
- 创建一个 JWT 实例。
- 设置 JWT 的声明(Claims)。
- 使用密钥对 JWT 进行签名。
示例
package main
import (
"fmt"
"time"
"github.com/golang-jwt/jwt/v5"
)
func generateJWT(userID string, secretKey []byte) (string, error) {
// 1. 创建 JWT 实例
token := jwt.New(jwt.SigningMethodHS256)
// 2. 设置 JWT 的声明(Claims)
claims := token.Claims.(jwt.MapClaims)
claims["user_id"] = userID
claims["exp"] = time.Now().Add(time.Hour * 24).Unix() // 设置过期时间为 24 小时后
// 3. 使用密钥对 JWT 进行签名
tokenString, err := token.SignedString(secretKey)
if err != nil {
return "", err
}
return tokenString, nil
}
func main() {
secretKey := []byte("your-256-bit-secret") // 密钥
userID := "12345" // 用户 ID
token, err := generateJWT(userID, secretKey)
if err != nil {
fmt.Println("Error generating JWT:", err)
return
}
fmt.Println("Generated JWT:", token)
}
3. 验证 JWT
步骤
- 解析 JWT 字符串。
- 验证 JWT 的签名和声明。
- 获取声明中的数据。
示例
func verifyJWT(tokenString string, secretKey []byte) (jwt.MapClaims, error) {
// 1. 解析 JWT 字符串
token, err := jwt.Parse(tokenString, func(token *jwt.Token) (interface{}, error) {
// 验证签名方法
if _, ok := token.Method.(*jwt.SigningMethodHMAC); !ok {
return nil, fmt.Errorf("unexpected signing method: %v", token.Header["alg"])
}
return secretKey, nil
})
// 2. 验证 JWT 的签名和声明
if err != nil {
return nil, err
}
if claims, ok := token.Claims.(jwt.MapClaims); ok && token.Valid {
return claims, nil
}
return nil, fmt.Errorf("invalid token")
}
func main() {
tokenString := "your.jwt.token.here" // 替换为生成的 JWT
claims, err := verifyJWT(tokenString, []byte("your-256-bit-secret"))
if err != nil {
fmt.Println("Error verifying JWT:", err)
return
}
fmt.Println("User ID:", claims["user_id"]) // 输出:User ID: 12345
}
4. 使用自定义 Claims
如果你需要更复杂的声明,可以定义自己的 Claims 结构。
示例
type CustomClaims struct {
UserID string `json:"user_id"`
jwt.RegisteredClaims
}
func generateCustomJWT(userID string, secretKey []byte) (string, error) {
// 1. 创建自定义声明
claims := CustomClaims{
UserID: userID,
RegisteredClaims: jwt.RegisteredClaims{
ExpiresAt: jwt.NewNumericDate(time.Now().Add(time.Hour * 24)), // 过期时间
IssuedAt: jwt.NewNumericDate(time.Now()), // 签发时间
},
}
// 2. 创建 JWT 实例
token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
// 3. 使用密钥对 JWT 进行签名
tokenString, err := token.SignedString(secretKey)
if err != nil {
return "", err
}
return tokenString, nil
}
5. 生成和验证 JWT 的完整示例
结合上述代码,以下是一个完整的示例:
package main
import (
"fmt"
"time"
"github.com/golang-jwt/jwt/v5"
)
type CustomClaims struct {
UserID string `json:"user_id"`
jwt.RegisteredClaims
}
func generateJWT(userID string, secretKey []byte) (string, error) {
claims := CustomClaims{
UserID: userID,
RegisteredClaims: jwt.RegisteredClaims{
ExpiresAt: jwt.NewNumericDate(time.Now().Add(time.Hour * 24)),
},
}
token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
tokenString, err := token.SignedString(secretKey)
if err != nil {
return "", err
}
return tokenString, nil
}
func verifyJWT(tokenString string, secretKey []byte) (*CustomClaims, error) {
token, err := jwt.ParseWithClaims(tokenString, &CustomClaims{}, func(token *jwt.Token) (interface{}, error) {
if _, ok := token.Method.(*jwt.SigningMethodHMAC); !ok {
return nil, fmt.Errorf("unexpected signing method: %v", token.Header["alg"])
}
return secretKey, nil
})
if err != nil {
return nil, err
}
if claims, ok := token.Claims.(*CustomClaims); ok && token.Valid {
return claims, nil
}
return nil, fmt.Errorf("invalid token")
}
func main() {
secretKey := []byte("your-256-bit-secret")
userID := "12345"
// 生成 JWT
token, err := generateJWT(userID, secretKey)
if err != nil {
fmt.Println("Error generating JWT:", err)
return
}
fmt.Println("Generated JWT:", token)
// 验证 JWT
claims, err := verifyJWT(token, secretKey)
if err != nil {
fmt.Println("Error verifying JWT:", err)
return
}
fmt.Println("User ID from JWT:", claims.UserID)
}
猜你喜欢
- 2025-03-10 seata-golang 接入指南
- 2025-03-10 Golang 入门系列(十三)介绍一个非常强大的web框架-Beego
- 2025-03-10 Golang实现gRPC的Proxy的原理
- 2025-03-10 Go语言学习(8) 第一个GO语言的GUI图形窗体
- 2025-03-10 使用 GORM 自动生成 Golang 代码
- 2025-03-10 golang性能优化实践
- 2025-03-10 超干货:Golang 简洁架构实战
- 2025-03-10 《Golang入门》一篇文章学完GO的基本语法《建议收藏》
- 最近发表
- 标签列表
-
- newcoder (56)
- 字符串的长度是指 (45)
- drawcontours()参数说明 (60)
- unsignedshortint (59)
- postman并发请求 (47)
- python列表删除 (50)
- 左程云什么水平 (56)
- 计算机网络的拓扑结构是指() (45)
- 稳压管的稳压区是工作在什么区 (45)
- 编程题 (64)
- postgresql默认端口 (66)
- 数据库的概念模型独立于 (48)
- 产生系统死锁的原因可能是由于 (51)
- 数据库中只存放视图的 (62)
- 在vi中退出不保存的命令是 (53)
- 哪个命令可以将普通用户转换成超级用户 (49)
- noscript标签的作用 (48)
- 联合利华网申 (49)
- swagger和postman (46)
- 结构化程序设计主要强调 (53)
- 172.1 (57)
- apipostwebsocket (47)
- 唯品会后台 (61)
- 简历助手 (56)
- offshow (61)