package auth import ( "net" "net/http" "strings" "time" ) // ExtractIP resolves the client's IP address from a request, accounting for the // reverse proxy in front of the backend. When the proxy forwards the original // address (X-Forwarded-For / X-Real-IP) the leftmost value is used; otherwise it // falls back to the connection's remote address. func ExtractIP(r *http.Request) string { if xff := r.Header.Get("X-Forwarded-For"); xff != "" { ips := strings.Split(xff, ",") return strings.TrimSpace(ips[0]) } if realIP := r.Header.Get("X-Real-IP"); realIP != "" { return realIP } ip, _, err := net.SplitHostPort(r.RemoteAddr) if err != nil { return r.RemoteAddr } return ip } func SigninSetup(w http.ResponseWriter, cookieName, cookieValue string, expiresAt time.Time, secure bool) { maxAge := expiresAt.Sub(time.Now().UTC()) http.SetCookie(w, &http.Cookie{ Name: cookieName, Value: cookieValue, Path: "/", HttpOnly: true, SameSite: http.SameSiteLaxMode, Secure: secure, MaxAge: int(maxAge.Seconds()), }) } func SignoutCleanup(w http.ResponseWriter, cookieName string, secure bool) { http.SetCookie(w, &http.Cookie{ Name: cookieName, Value: "", Path: "/", HttpOnly: true, Secure: secure, SameSite: http.SameSiteLaxMode, MaxAge: -1, }) }