新增功能: - 支持 Google Authenticator 等应用进行 TOTP 二次验证 - 用户可在个人设置中启用/禁用 2FA - 登录时支持 TOTP 验证流程 - 管理后台可全局开关 TOTP 功能 安全增强: - TOTP 密钥使用 AES-256-GCM 加密存储 - 添加 TOTP_ENCRYPTION_KEY 配置项,必须手动配置才能启用功能 - 防止服务重启导致加密密钥变更使用户无法登录 - 验证失败次数限制,防止暴力破解 配置说明: - Docker 部署:在 .env 中设置 TOTP_ENCRYPTION_KEY - 非 Docker 部署:在 config.yaml 中设置 totp.encryption_key - 生成密钥命令:openssl rand -hex 32
60 lines
2.1 KiB
Go
60 lines
2.1 KiB
Go
package routes
|
||
|
||
import (
|
||
"time"
|
||
|
||
"github.com/Wei-Shaw/sub2api/internal/handler"
|
||
"github.com/Wei-Shaw/sub2api/internal/middleware"
|
||
servermiddleware "github.com/Wei-Shaw/sub2api/internal/server/middleware"
|
||
|
||
"github.com/gin-gonic/gin"
|
||
"github.com/redis/go-redis/v9"
|
||
)
|
||
|
||
// RegisterAuthRoutes 注册认证相关路由
|
||
func RegisterAuthRoutes(
|
||
v1 *gin.RouterGroup,
|
||
h *handler.Handlers,
|
||
jwtAuth servermiddleware.JWTAuthMiddleware,
|
||
redisClient *redis.Client,
|
||
) {
|
||
// 创建速率限制器
|
||
rateLimiter := middleware.NewRateLimiter(redisClient)
|
||
|
||
// 公开接口
|
||
auth := v1.Group("/auth")
|
||
{
|
||
auth.POST("/register", h.Auth.Register)
|
||
auth.POST("/login", h.Auth.Login)
|
||
auth.POST("/login/2fa", h.Auth.Login2FA)
|
||
auth.POST("/send-verify-code", h.Auth.SendVerifyCode)
|
||
// 优惠码验证接口添加速率限制:每分钟最多 10 次(Redis 故障时 fail-close)
|
||
auth.POST("/validate-promo-code", rateLimiter.LimitWithOptions("validate-promo", 10, time.Minute, middleware.RateLimitOptions{
|
||
FailureMode: middleware.RateLimitFailClose,
|
||
}), h.Auth.ValidatePromoCode)
|
||
// 忘记密码接口添加速率限制:每分钟最多 5 次(Redis 故障时 fail-close)
|
||
auth.POST("/forgot-password", rateLimiter.LimitWithOptions("forgot-password", 5, time.Minute, middleware.RateLimitOptions{
|
||
FailureMode: middleware.RateLimitFailClose,
|
||
}), h.Auth.ForgotPassword)
|
||
// 重置密码接口添加速率限制:每分钟最多 10 次(Redis 故障时 fail-close)
|
||
auth.POST("/reset-password", rateLimiter.LimitWithOptions("reset-password", 10, time.Minute, middleware.RateLimitOptions{
|
||
FailureMode: middleware.RateLimitFailClose,
|
||
}), h.Auth.ResetPassword)
|
||
auth.GET("/oauth/linuxdo/start", h.Auth.LinuxDoOAuthStart)
|
||
auth.GET("/oauth/linuxdo/callback", h.Auth.LinuxDoOAuthCallback)
|
||
}
|
||
|
||
// 公开设置(无需认证)
|
||
settings := v1.Group("/settings")
|
||
{
|
||
settings.GET("/public", h.Setting.GetPublicSettings)
|
||
}
|
||
|
||
// 需要认证的当前用户信息
|
||
authenticated := v1.Group("")
|
||
authenticated.Use(gin.HandlerFunc(jwtAuth))
|
||
{
|
||
authenticated.GET("/auth/me", h.Auth.GetCurrentUser)
|
||
}
|
||
}
|