OAuth guides

Local OAuth development: localhost callbacks and mock issuers

Run your app on localhost while OAuth discovery, consent, and tokens come from a mock issuer. Loopback redirect URIs, stable env vars, and common pitfalls.

7 min read

Local OAuth development usually means two different hosts: your app on loopback, and a mock identity provider on HTTPS. The grant type, callback route, and library config match production; the issuer URL and client credentials point at a dev project on the mock service until you swap to Google, GitHub, or another real IdP.

Localhost and loopback redirect URIs

Your redirect URI is where the user lands after consent, almost always your local app:

  • http://localhost:3000/api/auth/callback
  • http://127.0.0.1:3000/api/auth/callback

Register that exact URL on the OAuth client in your project dashboard. localhost and 127.0.0.1 are different hosts; pick one and use it consistently. Trailing slashes must match registration.

The issuer URL is the mock provider origin plus project path, for example https://dummyoauth.com/p/your-project, copied from Integration snippets after you create a project.

Environment variables that should not change at deploy

Name variables after concepts, not vendors:

  • OIDC_ISSUER or OAUTH_ISSUER — mock issuer base (HTTPS, includes /p/your-slug).
  • OAUTH_CLIENT_ID / OAUTH_CLIENT_SECRET — from the project dashboard.
  • OAUTH_REDIRECT_URI or framework AUTH_URL — your localhost or deployed callback.

While building locally, set the issuer to your mock OAuth project. When you go live, change issuer and credentials to the real provider; keep variable names the same.

Issuer and discovery pitfalls

Libraries fetch {issuer}/.well-known/openid-configuration. The ID token iss claim must match your configured issuer string exactly. Common mistakes:

  • Trailing slash mismatch between env config and token iss.
  • Mixing issuer paths from two different projects.

HTTP for your app, HTTPS for the issuer

Loopback callbacks are often http://. The mock issuer uses https://. Set Secure and SameSite on session cookies explicitly so production behavior does not depend on dev-only quirks.

Swapping to a real provider later

Before cutover, verify scopes, claim names, and whether the provider returns id_token on the token response or requires UserInfo. See authorization code flow and OpenID Connect basics.