refactor(auth): replace dashboard sessions with stateless tokens and session control (#6329)

* refactor(auth): replace dashboard sessions with stateless tokens

* feat(auth): harden session issuance and distributed enforcement

* fix(proxy): preserve trusted proxy compatibility defaults

* refactor: address dashboard auth review feedback

* refactor: remove classic frontend and flatten web app
This commit is contained in:
Calcium-Ion
2026-07-20 16:48:43 +08:00
committed by GitHub
parent 5a6c53d496
commit 31d70fca39
1605 changed files with 17511 additions and 147913 deletions
+76
View File
@@ -0,0 +1,76 @@
package middleware
import (
"crypto/subtle"
"net/http"
"net/url"
"strings"
"github.com/QuantumNous/new-api/common"
"github.com/gin-gonic/gin"
)
// SessionCookieOriginGuard protects cookie-authenticated refresh/logout
// endpoints when secure cookie mode is enabled. In insecure local development
// mode it preserves the legacy behavior and intentionally performs no Origin
// validation. It never adds CORS response headers and must not be installed on
// relay routes.
func SessionCookieOriginGuard() gin.HandlerFunc {
return func(c *gin.Context) {
if !common.SessionCookieSecure {
c.Next()
return
}
origin, ok := requestBrowserOrigin(c.Request)
if !ok || !isAllowedSessionOrigin(c.Request, origin) {
c.AbortWithStatusJSON(http.StatusForbidden, gin.H{
"success": false,
"code": "AUTH_ORIGIN_FORBIDDEN",
"message": "request origin is not allowed",
})
return
}
c.Next()
}
}
func requestBrowserOrigin(request *http.Request) (string, bool) {
originValues := request.Header.Values("Origin")
if len(originValues) > 1 {
return "", false
}
if len(originValues) == 1 {
if strings.Contains(originValues[0], ",") {
return "", false
}
origin, err := common.NormalizeOrigin(originValues[0])
return origin, err == nil
}
refererValues := request.Header.Values("Referer")
if len(refererValues) != 1 {
return "", false
}
referer, err := url.Parse(strings.TrimSpace(refererValues[0]))
if err != nil || referer.Scheme == "" || referer.Host == "" || referer.User != nil {
return "", false
}
origin, err := common.NormalizeOrigin(referer.Scheme + "://" + referer.Host)
return origin, err == nil
}
func isAllowedSessionOrigin(request *http.Request, origin string) bool {
requestScheme := "http"
if request.TLS != nil {
requestScheme = "https"
}
requestOrigin, err := common.NormalizeOrigin(requestScheme + "://" + request.Host)
if err == nil && subtle.ConstantTimeCompare([]byte(origin), []byte(requestOrigin)) == 1 {
return true
}
for _, trustedOrigin := range common.SessionCookieTrustedURLs {
if subtle.ConstantTimeCompare([]byte(origin), []byte(trustedOrigin)) == 1 {
return true
}
}
return false
}