本提交重构了全栈的认证与安全体系,包含以下核心变更: 1. **后端安全增强**: - 使用常量时间比较修复CSRF校验时序漏洞 - 重构refresh token存储为哈希+密文,支持轮转宽限期与盗用检测 - 新增cookie前缀自动配置,支持__Host-前缀强化生产环境安全 - 优化登出逻辑为单设备登出,合并用户信息与未读通知接口 - 增加数据库迁移脚本,兼容旧版refresh token数据升级 - 新增定时清理过期refresh token任务 2. **前端安全与体验优化**: - 新增cookie工具库,统一管理认证cookie名与转发逻辑 - 修复开放重定向漏洞,实现安全跳转校验 - 重构SSR请求逻辑,仅转发必要的access token cookie - 优化middleware轮转逻辑,修复并发请求去重与边缘部署兼容性 - 修复登录态静默校正逻辑,兼容旧版cookie路径与名称 - 新增环境变量示例配置文件 3. **工程化改进**: 修复Next.js类型文件导入路径,统一前后端配置与命名规范
38 lines
1.1 KiB
Go
38 lines
1.1 KiB
Go
package middleware
|
|
|
|
import (
|
|
"crypto/subtle"
|
|
"net/http"
|
|
|
|
"github.com/freefire/jiang13-bbs/service"
|
|
"github.com/gin-gonic/gin"
|
|
)
|
|
|
|
// CSRFMiddleware CSRF 防护中间件
|
|
// 对 POST/PUT/DELETE 等状态变更请求,校验 X-CSRF-Token header 与 cookie 中的 CSRF token 是否一致
|
|
func CSRFMiddleware() gin.HandlerFunc {
|
|
return func(c *gin.Context) {
|
|
// 仅对状态变更方法校验
|
|
if c.Request.Method == http.MethodGet || c.Request.Method == http.MethodHead || c.Request.Method == http.MethodOptions {
|
|
c.Next()
|
|
return
|
|
}
|
|
|
|
cookieToken, err := c.Cookie(service.CSRFCookieName)
|
|
if err != nil || cookieToken == "" {
|
|
c.AbortWithStatusJSON(http.StatusForbidden, gin.H{"error": "CSRF token 缺失"})
|
|
return
|
|
}
|
|
|
|
headerToken := c.GetHeader(service.CSRFHeaderName)
|
|
// 常量时间比较,避免通过响应耗时逐字节猜测 CSRF token
|
|
if headerToken == "" ||
|
|
subtle.ConstantTimeCompare([]byte(headerToken), []byte(cookieToken)) != 1 {
|
|
c.AbortWithStatusJSON(http.StatusForbidden, gin.H{"error": "CSRF 校验失败"})
|
|
return
|
|
}
|
|
|
|
c.Next()
|
|
}
|
|
}
|