mirror of
https://github.com/black-ant/Ant-Browser.git
synced 2026-07-14 18:48:55 +08:00
channel: master version: 1.1.0 source-ref: master published-at-utc: 2026-03-29T11:32:04Z
94 lines
2.0 KiB
Go
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)
|
|
})
|
|
}
|