Serve Firebase's auth handler from our own domain
Google sign-in fails in production: the popup opens, flashes, closes, and the page shows a generic failure with nothing in the console or the network tab. The app is served from drb.cusano.net while signInWithPopup opens its handler on the project's firebaseapp.com origin. Chrome partitions third-party storage, so the popup cannot read back the state its opener wrote and dies immediately. Visiting the handler directly says so: "missing initial state ... a storage-partitioned browser environment". Nothing about authorised domains or the build was wrong -- the shipped bundle carries the correct apiKey and authDomain, which is exactly what made this look like a code bug. Caddy now proxies /__/auth/* on the bare domain to the Firebase Hosting origin, rewriting Host so Firebase recognises the request. Same-site again, which is Google's documented fix. The vhost becomes a `route` so the handler matches before the catch-all proxy to Next. The upstream host is a jinja default rather than a group_vars entry because group_vars/all.yml is gitignored; override it there if the project ever moves. Two manual steps remain, and all three parts are required or nothing changes: the CI secret FIREBASE_AUTH_DOMAIN must become drb.cusano.net with a frontend rebuild, and drb.cusano.net must be an authorised domain in the Firebase console. This template also needs an ansible run -- CI alone will not deploy it. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5
parent
4dc3f27ac4
commit
157be0c049
@@ -35,7 +35,31 @@ mqtt.{{ domain }} {
|
|||||||
# To move it to app.{{ domain }}, create the A record first, then change this
|
# To move it to app.{{ domain }}, create the A record first, then change this
|
||||||
# line — the reverse_proxy target stays the same either way.
|
# line — the reverse_proxy target stays the same either way.
|
||||||
{{ domain }} {
|
{{ domain }} {
|
||||||
|
route {
|
||||||
|
# Firebase Auth's sign-in handler, served from our own origin.
|
||||||
|
#
|
||||||
|
# signInWithPopup opens {{ firebase_auth_handler_host | default('discord-radio-bot-461301.firebaseapp.com') }}/__/auth/handler and
|
||||||
|
# then reads back state the opener wrote. Chrome now partitions third-party
|
||||||
|
# storage, so when that handler is on a different site from the app the
|
||||||
|
# popup cannot see that state: it opens, fails, and closes instantly with no
|
||||||
|
# console or network trace. The handler page says so itself if you visit it
|
||||||
|
# directly ("storage-partitioned browser environment").
|
||||||
|
#
|
||||||
|
# Proxying the handler through this domain makes it same-site, which is
|
||||||
|
# Google's documented fix. Host must be rewritten upstream or Firebase
|
||||||
|
# Hosting will not recognise the request.
|
||||||
|
#
|
||||||
|
# NEXT_PUBLIC_FIREBASE_AUTH_DOMAIN must be set to {{ domain }} in the CI
|
||||||
|
# build secrets to match, and {{ domain }} must be listed in the Firebase
|
||||||
|
# console's authorised domains. Changing only one of the three does nothing.
|
||||||
|
handle /__/auth/* {
|
||||||
|
reverse_proxy https://{{ firebase_auth_handler_host | default('discord-radio-bot-461301.firebaseapp.com') }} {
|
||||||
|
header_up Host {{ firebase_auth_handler_host | default('discord-radio-bot-461301.firebaseapp.com') }}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
reverse_proxy localhost:3000 {
|
reverse_proxy localhost:3000 {
|
||||||
header_up X-Forwarded-For {remote_host}
|
header_up X-Forwarded-For {remote_host}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user