0d84b07f68
CI / docker (push) Successful in 1m58s
Go + Vue 管理台:Agent 隧道、域名反代、IP 安全、访客验证与监控大盘。 Gitea Actions CI 多架构镜像;纯 Go SQLite、无 CGO Docker 构建。 Co-authored-by: Cursor <cursoragent@cursor.com>
56 lines
1.4 KiB
Go
56 lines
1.4 KiB
Go
package auth
|
|
|
|
import (
|
|
"net"
|
|
"net/http"
|
|
"strings"
|
|
)
|
|
|
|
// DirectRemoteIP returns the direct TCP peer address, ignoring X-Forwarded-For.
|
|
// Use for security decisions (login rate limit, IP rules, resource auth).
|
|
func DirectRemoteIP(r *http.Request) string {
|
|
return HostOnly(r.RemoteAddr)
|
|
}
|
|
|
|
// AddrHost extracts the host portion from a net.Addr string (host:port or [host]:port).
|
|
func AddrHost(addr net.Addr) string {
|
|
if addr == nil {
|
|
return ""
|
|
}
|
|
return HostOnly(addr.String())
|
|
}
|
|
|
|
// HostOnly strips the port from an address string.
|
|
func HostOnly(addr string) string {
|
|
if addr == "" {
|
|
return ""
|
|
}
|
|
host, _, err := net.SplitHostPort(addr)
|
|
if err != nil {
|
|
return strings.Trim(addr, "[]")
|
|
}
|
|
return host
|
|
}
|
|
|
|
// ExtractRemoteIP returns the client IP, honoring X-Forwarded-For when present.
|
|
// Use only when forwarding visitor IP to upstream backends behind a trusted proxy.
|
|
func ExtractRemoteIP(r *http.Request) string {
|
|
if xff := r.Header.Get("X-Forwarded-For"); xff != "" {
|
|
parts := strings.Split(xff, ",")
|
|
return strings.TrimSpace(parts[0])
|
|
}
|
|
if xri := r.Header.Get("X-Real-IP"); xri != "" {
|
|
return strings.TrimSpace(xri)
|
|
}
|
|
return DirectRemoteIP(r)
|
|
}
|
|
|
|
// SafeRedirectPath validates a post-login redirect path (relative only).
|
|
func SafeRedirectPath(raw string) string {
|
|
raw = strings.TrimSpace(raw)
|
|
if raw == "" || !strings.HasPrefix(raw, "/") || strings.HasPrefix(raw, "//") {
|
|
return "/"
|
|
}
|
|
return raw
|
|
}
|