Self-heal duplicate session cookies from the Domain rollout

Browsers that logged in before the session cookie became Domain-scoped
still hold the old host-only descrybe_session for api.descrybe.io. They
then send BOTH cookies — older (stale) first — and Go reads the first
match, so the stale relic shadows the fresh Domain cookie and every
request 401s even immediately after a successful login. Clearing
browser cookies fixed it manually; users should never have to.

New DedupeSessionCookies middleware (mounted before scs LoadAndSave):
when duplicate session cookies arrive, pick the token that resolves in
the session store, rewrite the Cookie header to just that one, expire
the host-only relic (Set-Cookie without Domain only touches the
host-only variant), and re-issue the surviving token on the canonical
Domain cookie. One request converges the browser to a single cookie.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
2026-08-18 01:19:46 +02:00
co-authored by Claude Fable 5
parent d03c2a5c57
commit 6facfbb0aa
3 changed files with 194 additions and 0 deletions
+3
View File
@@ -316,6 +316,9 @@ func (s *Server) Router() http.Handler {
r.Group(func(r chi.Router) {
// Maintenance/read-only before session+CSRF so freeze returns 503 (not csrf 403).
r.Use(s.MaintenanceGate)
// Collapse stale host-only + Domain session cookie duplicates before scs
// reads the request (see DedupeSessionCookies).
r.Use(s.DedupeSessionCookies)
r.Use(LoadSession(s.Sessions))
r.Use(s.CSRF)