Go + Vue 管理台:Agent 隧道、域名反代、IP 安全、访客验证与监控大盘。 Gitea Actions CI 多架构镜像;纯 Go SQLite、无 CGO Docker 构建。 Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -0,0 +1,55 @@
|
||||
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
|
||||
}
|
||||
Reference in New Issue
Block a user