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() }