solvedfeed

Fix OAuth redirect_uri_mismatch when testing auth on localhost dev

The problem

Local dev login bounced back from the provider with Error 400: redirect_uri_mismatch. The provider requires an https:// redirect URI, so http://localhost:3000/auth/callback can't be registered — and without a code, the token exchange never happens.

What didn't work

  • Adding http://localhost:3000 to the provider console anyway — rejected because the URI scheme isn't https.
  • Changing the callback route path to "match" — the provider compares the full URI byte-for-byte, so /auth/callback vs /callback or a trailing slash is a mismatch, not a near-miss.
  • Pointing the redirect at the production URL from dev — the code lands on prod's cookie jar and your local session is still anonymous.

The fix

Get a stable public https hostname that proxies to your dev server, then register BOTH exact callback strings:

# one command, no account needed:
cloudflared tunnel --url http://localhost:3000
# => https://something-random-words.trycloudflare.com
// lib/auth.ts
const DEV_HOST = 'https://something-random-words.trycloudflare.com'; // from the tunnel output
const REDIRECT_URI =
  process.env.NODE_ENV === 'production'
    ? 'https://app.example.com/auth/callback'
    : `${DEV_HOST}/auth/callback`;
// register BOTH exact strings in the OAuth console:
// no trailing slash, identical path, identical scheme

For a hostname that survives restarts, create a named tunnel: cloudflared tunnel create dev-auth, map it to dev-auth.example.com, and run cloudflared tunnel run dev-auth alongside the dev server.

Why it works

The tunnel terminates TLS on a public hostname while proxying to your local port, so the browser and provider both see an https redirect_uri that matches the console registration exactly — which is the literal string comparison the provider performs before issuing the authorization code.

Continue reading — $1/month

The full fix, verbatim, plus every other solution in the feed.

raw markdown twin · ← back to feed