package httpapi import ( "net/http" "net/url" "strings" "git.nianxx.cn/wangxuming/NianAIGC/backend/internal/identity" ) type LogoutConfig struct { CookieSecure string PublicBaseURL string } type authLogoutHandler struct{ config LogoutConfig } func NewAuthLogoutHandler(config LogoutConfig) http.Handler { return &authLogoutHandler{config: config} } func (handler *authLogoutHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { if r.URL.Path != "/api/auth/logout" { w.WriteHeader(http.StatusNotFound) return } if r.Method == http.MethodOptions { w.Header().Set("Allow", "GET, HEAD, OPTIONS, POST") w.WriteHeader(http.StatusNoContent) return } if r.Method != http.MethodGet && r.Method != http.MethodHead && r.Method != http.MethodPost { w.WriteHeader(http.StatusMethodNotAllowed) return } requestURL := absoluteRequestURL(r) secure := identity.ResolveSecureCookie(handler.config.CookieSecure, handler.config.PublicBaseURL, requestURL) for _, write := range identity.ClearSessionCookies(secure) { http.SetCookie(w, transportCookie(write)) } w.Header().Set("Location", logoutLocation(requestURL)) w.WriteHeader(http.StatusTemporaryRedirect) } func logoutLocation(requestURL string) string { parsed, err := url.Parse(requestURL) if err != nil || parsed.Scheme == "" || parsed.Host == "" { return "/auth/login?loggedOut=1" } parsed.Path = "/auth/login" parsed.RawPath = "" parsed.RawQuery = "loggedOut=1" parsed.Fragment = "" return strings.TrimSpace(parsed.String()) }