Files
Ant-Browser/backend/internal/launchcode/auth.go
T
Ant Browser Release Bot 3d264eb83d publish: 1.1.0 snapshot (a358335)
channel: master
version: 1.1.0
source-ref: master
published-at-utc: 2026-03-29T11:32:04Z
2026-03-29 19:32:05 +08:00

94 lines
2.0 KiB
Go

package launchcode
import (
"crypto/subtle"
"net/http"
"strings"
)
const DefaultAPIKeyHeader = "X-Ant-Api-Key"
// APIAuthConfig 定义 LaunchServer 对 /api/* 请求的可选认证配置。
type APIAuthConfig struct {
Enabled bool
APIKey string
Header string
}
func normalizeAPIAuthConfig(cfg APIAuthConfig) APIAuthConfig {
cfg.APIKey = strings.TrimSpace(cfg.APIKey)
cfg.Header = strings.TrimSpace(cfg.Header)
if cfg.Header == "" {
cfg.Header = DefaultAPIKeyHeader
}
return cfg
}
func (cfg APIAuthConfig) Requested() bool {
return cfg.Enabled
}
func (cfg APIAuthConfig) Configured() bool {
return cfg.APIKey != ""
}
func (cfg APIAuthConfig) Active() bool {
return cfg.Requested() && cfg.Configured()
}
func (s *LaunchServer) SetAPIAuthConfig(cfg APIAuthConfig) {
s.authMu.Lock()
s.apiAuth = normalizeAPIAuthConfig(cfg)
s.authMu.Unlock()
}
func (s *LaunchServer) apiAuthConfig() APIAuthConfig {
s.authMu.RLock()
cfg := s.apiAuth
s.authMu.RUnlock()
return cfg
}
func (s *LaunchServer) APIAuthHeader() string {
return s.apiAuthConfig().Header
}
func (s *LaunchServer) APIAuthRequested() bool {
return s.apiAuthConfig().Requested()
}
func (s *LaunchServer) APIAuthConfigured() bool {
return s.apiAuthConfig().Configured()
}
func (s *LaunchServer) APIAuthEnabled() bool {
return s.apiAuthConfig().Active()
}
func (s *LaunchServer) apiAuthMiddleware(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if !strings.HasPrefix(r.URL.Path, "/api/") {
next.ServeHTTP(w, r)
return
}
cfg := s.apiAuthConfig()
if !cfg.Active() {
next.ServeHTTP(w, r)
return
}
providedKey := strings.TrimSpace(r.Header.Get(cfg.Header))
if subtle.ConstantTimeCompare([]byte(providedKey), []byte(cfg.APIKey)) != 1 {
writeJSON(w, http.StatusUnauthorized, map[string]interface{}{
"ok": false,
"error": "unauthorized: invalid api key",
"authHeader": cfg.Header,
})
return
}
next.ServeHTTP(w, r)
})
}