mirror of
https://github.com/QuantumNous/new-api.git
synced 2026-03-30 03:43:39 +00:00
132 lines
3.2 KiB
Go
132 lines
3.2 KiB
Go
package middleware
|
||
|
||
import (
|
||
"net/http"
|
||
"time"
|
||
|
||
"github.com/gin-contrib/sessions"
|
||
"github.com/gin-gonic/gin"
|
||
)
|
||
|
||
const (
|
||
// SecureVerificationSessionKey 安全验证的 session key(与 controller 保持一致)
|
||
SecureVerificationSessionKey = "secure_verified_at"
|
||
// SecureVerificationTimeout 验证有效期(秒)
|
||
SecureVerificationTimeout = 300 // 5分钟
|
||
)
|
||
|
||
// SecureVerificationRequired 安全验证中间件
|
||
// 检查用户是否在有效时间内通过了安全验证
|
||
// 如果未验证或验证已过期,返回 401 错误
|
||
func SecureVerificationRequired() gin.HandlerFunc {
|
||
return func(c *gin.Context) {
|
||
// 检查用户是否已登录
|
||
userId := c.GetInt("id")
|
||
if userId == 0 {
|
||
c.JSON(http.StatusUnauthorized, gin.H{
|
||
"success": false,
|
||
"message": "未登录",
|
||
})
|
||
c.Abort()
|
||
return
|
||
}
|
||
|
||
// 检查 session 中的验证时间戳
|
||
session := sessions.Default(c)
|
||
verifiedAtRaw := session.Get(SecureVerificationSessionKey)
|
||
|
||
if verifiedAtRaw == nil {
|
||
c.JSON(http.StatusForbidden, gin.H{
|
||
"success": false,
|
||
"message": "需要安全验证",
|
||
"code": "VERIFICATION_REQUIRED",
|
||
})
|
||
c.Abort()
|
||
return
|
||
}
|
||
|
||
verifiedAt, ok := verifiedAtRaw.(int64)
|
||
if !ok {
|
||
// session 数据格式错误
|
||
session.Delete(SecureVerificationSessionKey)
|
||
_ = session.Save()
|
||
c.JSON(http.StatusForbidden, gin.H{
|
||
"success": false,
|
||
"message": "验证状态异常,请重新验证",
|
||
"code": "VERIFICATION_INVALID",
|
||
})
|
||
c.Abort()
|
||
return
|
||
}
|
||
|
||
// 检查验证是否过期
|
||
elapsed := time.Now().Unix() - verifiedAt
|
||
if elapsed >= SecureVerificationTimeout {
|
||
// 验证已过期,清除 session
|
||
session.Delete(SecureVerificationSessionKey)
|
||
_ = session.Save()
|
||
c.JSON(http.StatusForbidden, gin.H{
|
||
"success": false,
|
||
"message": "验证已过期,请重新验证",
|
||
"code": "VERIFICATION_EXPIRED",
|
||
})
|
||
c.Abort()
|
||
return
|
||
}
|
||
|
||
// 验证有效,继续处理请求
|
||
c.Next()
|
||
}
|
||
}
|
||
|
||
// OptionalSecureVerification 可选的安全验证中间件
|
||
// 如果用户已验证,则在 context 中设置标记,但不阻止请求继续
|
||
// 用于某些需要区分是否已验证的场景
|
||
func OptionalSecureVerification() gin.HandlerFunc {
|
||
return func(c *gin.Context) {
|
||
userId := c.GetInt("id")
|
||
if userId == 0 {
|
||
c.Set("secure_verified", false)
|
||
c.Next()
|
||
return
|
||
}
|
||
|
||
session := sessions.Default(c)
|
||
verifiedAtRaw := session.Get(SecureVerificationSessionKey)
|
||
|
||
if verifiedAtRaw == nil {
|
||
c.Set("secure_verified", false)
|
||
c.Next()
|
||
return
|
||
}
|
||
|
||
verifiedAt, ok := verifiedAtRaw.(int64)
|
||
if !ok {
|
||
c.Set("secure_verified", false)
|
||
c.Next()
|
||
return
|
||
}
|
||
|
||
elapsed := time.Now().Unix() - verifiedAt
|
||
if elapsed >= SecureVerificationTimeout {
|
||
session.Delete(SecureVerificationSessionKey)
|
||
_ = session.Save()
|
||
c.Set("secure_verified", false)
|
||
c.Next()
|
||
return
|
||
}
|
||
|
||
c.Set("secure_verified", true)
|
||
c.Set("secure_verified_at", verifiedAt)
|
||
c.Next()
|
||
}
|
||
}
|
||
|
||
// ClearSecureVerification 清除安全验证状态
|
||
// 用于用户登出或需要强制重新验证的场景
|
||
func ClearSecureVerification(c *gin.Context) {
|
||
session := sessions.Default(c)
|
||
session.Delete(SecureVerificationSessionKey)
|
||
_ = session.Save()
|
||
}
|