Files
spsays-bff/pkg/auth/cookie.go
T
2026-05-30 02:33:57 +05:30

57 lines
1.5 KiB
Go

package auth
import (
"net/http"
"time"
)
// CookieName is the single httpOnly cookie that carries the JWT.
const CookieName = "spsays_auth"
// CookieOptions captures the per-environment knobs for the auth cookie.
type CookieOptions struct {
Domain string // empty in dev; ".prabhupadasays.org" in prod for subdomain sharing
Secure bool // true in production (HTTPS-only)
}
// Set writes the JWT into a Secure, httpOnly, SameSite=Lax cookie.
// SameSite=Lax + same-registrable-domain (prabhupadasays.org / api.prabhupadasays.org)
// is enough for cross-subdomain auth without resorting to SameSite=None.
func Set(w http.ResponseWriter, token string, expires time.Time, opts CookieOptions) {
http.SetCookie(w, &http.Cookie{
Name: CookieName,
Value: token,
Path: "/",
Domain: opts.Domain,
Expires: expires,
MaxAge: int(time.Until(expires).Seconds()),
HttpOnly: true,
Secure: opts.Secure,
SameSite: http.SameSiteLaxMode,
})
}
// Clear overwrites the auth cookie with an immediately-expired one.
func Clear(w http.ResponseWriter, opts CookieOptions) {
http.SetCookie(w, &http.Cookie{
Name: CookieName,
Value: "",
Path: "/",
Domain: opts.Domain,
Expires: time.Unix(0, 0),
MaxAge: -1,
HttpOnly: true,
Secure: opts.Secure,
SameSite: http.SameSiteLaxMode,
})
}
// Read pulls the raw JWT out of the request cookie. Returns "" if missing.
func Read(r *http.Request) string {
c, err := r.Cookie(CookieName)
if err != nil {
return ""
}
return c.Value
}