Files
smartmate/backend/auth/jwt_generater.go
LoveLosita 78aa38a6f3 Version:0.0.1.dev.260202
feat: build core architecture & implement user auth modules 🚀
feat: 搭建核心架构并实现用户认证模块 🚀

Framework Migration: Switched from Hertz to Gin, providing a more idiomatic and lightweight web foundation. 
框架迁移:从 Hertz 切换至 Gin,构建了更符合 Go 惯例且轻量级的 Web 基础。

Architectural Overhaul: Refactored the 3-layer architecture from global-variable-based calls to Explicit Dependency Injection (DI) via New... factory functions. This significantly improves testability and decoupling. 🏗️
架构重构:将三层架构从基于“全局变量”的调用重构为通过 New... 工厂函数实现的显式依赖注入 (DI)。这大幅提升了代码的可测试性与解耦程度。🏗️

User Auth: Completed and tested Register, Login, and Token Refresh APIs with robust error handling and Bcrypt password hashing. 🔐
用户认证:完成了注册、登录与 Token 刷新接口并通过测试,包含健壮的错误处理与 Bcrypt 密码哈希加密。🔐

Config Management: Integrated Viper for centralized, environment-aware configuration management. ⚙️
配置管理:集成了 Viper,实现了中心化且具备环境感知能力的配置管理。⚙️

DevOps & Docs:
Added docker-compose.yml for seamless MySQL 8.0 & environment setup. 🐳
Updated README.md with corrections for mistakes in image quoting and formats. 📝
运维与文档:
新增 docker-compose.yml,实现 MySQL 8.0 环境的一键启动。🐳
更新 README.md,修改了一些图片引用和格式上小错误。📝
2026-02-02 21:32:21 +08:00

69 lines
2.2 KiB
Go

package auth
import (
"time"
"github.com/golang-jwt/jwt/v4"
"github.com/smartflow/backend/respond"
"github.com/spf13/viper"
)
var RefreshKey = []byte(viper.GetString("jwt.accessSecret")) // 用于签名和验证刷新Token的密钥
var AccessKey = []byte(viper.GetString("jwt.refreshSecret")) // 用于签名和验证访问Token的密钥
// GenerateTokens 生成访问令牌和刷新令牌
func GenerateTokens(userID int) (string, string, error) {
// 创建访问令牌
accessToken := jwt.NewWithClaims(jwt.SigningMethodHS256, jwt.MapClaims{
"user_id": userID, // 获取用户ID
"exp": time.Now().Add(15 * time.Minute).Unix(), // 设置访问令牌过期时间为 15 分钟
"token_type": "access_token", // 令牌类型为访问令牌
})
// 使用密钥签名访问令牌
accessTokenString, err := accessToken.SignedString(AccessKey)
if err != nil {
return "", "", err
}
// 创建刷新令牌
refreshToken := jwt.NewWithClaims(jwt.SigningMethodHS256, jwt.MapClaims{
"user_id": userID, // 获取用户ID
"exp": time.Now().Add(7 * 24 * time.Hour).Unix(), // 设置刷新令牌过期时间为 7 天
"token_type": "refresh_token", // 令牌类型为刷新令牌
})
// 使用密钥签名刷新令牌
refreshTokenString, err := refreshToken.SignedString(RefreshKey)
if err != nil {
return "", "", err
}
return accessTokenString, refreshTokenString, nil
}
func ValidateRefreshToken(tokenString string) (*jwt.Token, error) {
token, err := jwt.Parse(tokenString, func(token *jwt.Token) (interface{}, error) {
// 检查签名方法是否为 HMAC
if _, ok := token.Method.(*jwt.SigningMethodHMAC); !ok {
return nil, respond.InvalidTokenSingingMethod
}
// 返回用于验证的密钥
return RefreshKey, nil
})
if err != nil {
return nil, err
}
// 进一步检查载荷中 token_type 是否正确
claims, ok := token.Claims.(jwt.MapClaims)
if !ok {
return nil, respond.InvalidClaims
}
// 检查 token_type 是否是 refresh_token
if claimType, ok := claims["token_type"].(string); !ok || claimType != "refresh_token" {
return nil, respond.WrongTokenType
}
return token, nil
}