fix: auth login ways

This commit is contained in:
engigu
2026-03-12 09:57:34 +08:00
parent 8e1df7a55a
commit dd5bef9733
7 changed files with 122 additions and 36 deletions
+23 -11
View File
@@ -1,6 +1,8 @@
package middleware
import (
"crypto/sha256"
"crypto/subtle"
"encoding/json"
"net/http"
"time"
@@ -26,17 +28,16 @@ func AuthRequired() gin.HandlerFunc {
}
// 验证 token
userID, username, err := utils.ParseToken(token, constant.Secret)
userID, username, tokenVersion, err := utils.ParseToken(token, constant.Secret)
if err != nil {
utils.Unauthorized(c, "登录已过期,请重新登录")
c.Abort()
return
}
// 安全增强:校验数据库中该用户的 ID 是否与 Token 一致
// 防止迁移后旧 Token 中的数字 ID 污染新数据
// 安全增强:校验数据库中该用户的 ID 是否与 Token 一致,并验证 TokenVersion
var user models.User
if err := database.DB.Where("username = ?", username).First(&user).Error; err != nil || user.ID != userID {
if err := database.DB.Where("username = ?", username).First(&user).Error; err != nil || user.ID != userID || user.TokenVersion != tokenVersion {
utils.Unauthorized(c, "会话失效,请重新登录")
ClearAuthCookie(c)
c.Abort()
@@ -101,7 +102,14 @@ func checkOpenapiToken(c *gin.Context, settingsSvc *services.SettingsService) bo
return false
}
if tokenConfig.Token == "" || openapiToken != tokenConfig.Token {
if tokenConfig.Token == "" {
return false
}
// 使用恒定时间比较防止时序攻击
h1 := sha256.Sum256([]byte(openapiToken))
h2 := sha256.Sum256([]byte(tokenConfig.Token))
if subtle.ConstantTimeCompare(h1[:], h2[:]) != 1 {
return false
}
@@ -200,13 +208,17 @@ func SwaggerAuth() gin.HandlerFunc {
}
// 检查提供的 token 是否匹配
if providedToken != "" && providedToken == tokenConfig.Token {
// 如果是通过 url 参数进来的,自动将其种入 Cookie,便于后续加载静态资源 (如 json)
if tokenQuery != "" {
c.SetCookie("openapi_token", providedToken, 86400, "/openapi", "", false, false)
if providedToken != "" {
h1 := sha256.Sum256([]byte(providedToken))
h2 := sha256.Sum256([]byte(tokenConfig.Token))
if subtle.ConstantTimeCompare(h1[:], h2[:]) == 1 {
// 如果是通过 url 参数进来的,自动将其种入 Cookie,便于后续加载静态资源 (如 json)
if tokenQuery != "" {
c.SetCookie("openapi_token", providedToken, 86400, "/openapi", "", false, false)
}
c.Next()
return
}
c.Next()
return
}
// 验证失败,不再返回 WWW-Authenticate 头触发浏览器反人类原生弹窗