Radon
Auth Methods

Google

Sign in with Google — free, no license required. Radon handles the OAuth exchange, fetches the profile, and merges by verified email.

Google sign-in is part of the free tier (the other 50 OAuth providers are Pro). Radon builds the consent URL, exchanges the code for tokens, fetches the user's profile, and resolves them to a user by verified email.

1. Create Google credentials

In the Google Cloud ConsoleAPIs & Services → Credentials, create an OAuth 2.0 Client ID (type: Web application).

Under Authorized redirect URIs, add your callback URL, e.g. https://acme.com/api/auth/google/callback. This must match redirectUri exactly.

Copy the Client ID and Client secret.

2. Enable the provider

lib/auth.ts
export const auth = new Radon({
  adapter: postgresAdapter(pool),
  session: { secret: process.env.RADON_SECRET! },
  providers: {
    google: {
      clientId: process.env.RADON_GOOGLE_CLIENT_ID!,
      clientSecret: process.env.RADON_GOOGLE_CLIENT_SECRET!,
      redirectUri: "https://acme.com/api/auth/google/callback",
    },
  },
});

Credentials can come from the environment

If you set RADON_GOOGLE_CLIENT_ID, RADON_GOOGLE_CLIENT_SECRET, and RADON_GOOGLE_REDIRECT_URI, you can omit them from the config entirely — providers: { google: {} } is enough.

OptionTypeDescription
clientIdstringFalls back to RADON_GOOGLE_CLIENT_ID.
clientSecretstringFalls back to RADON_GOOGLE_CLIENT_SECRET.
redirectUristringFalls back to RADON_GOOGLE_REDIRECT_URI. Must match the console.
scopesstring[]Default ["openid", "email", "profile"].

3. Use it over HTTP

Method & pathQueryEffect
GET /google/start?state=…Redirects the user to Google's consent screen
GET /google/callback?code=…&state=…Signs in → sets cookie, then redirects

You don't fetch these — you send the user's browser to them. A "Sign in with Google" button is just a link:

Frontend
<a href="/api/auth/google/start">Sign in with Google</a>

Google redirects back to /api/auth/google/callback, Radon completes the exchange, sets the radon_session cookie, and 302-redirects to your successRedirect (default /). Configure that in the framework handler.

4. Or call it directly in code

If you're wiring the flow yourself (no HTTP integration):

// 1. Build the consent URL and redirect the user to it.
const url = auth.google.getAuthUrl({ state: csrfToken });
// → returns a string. `redirect(url)`.

// 2. On your callback route, exchange the `code` query param:
const { user, created, profile } = await auth.google.handleCallback(code);
const { token } = auth.createSessionToken(user.id); // issue a session yourself

Google's getAuthUrl returns a string

auth.google.getAuthUrl(...) returns the URL as a string. (The Pro OAuth providers return an object { url, codeVerifier?, state? } instead, because they support PKCE — don't mix the two up.)

getAuthUrl options

auth.google.getAuthUrl({
  state: "csrf-token",          // echoed back on the callback — use it for CSRF
  scopes: ["openid", "email"],  // override the default scopes
  accessType: "offline",        // request a refresh token
  prompt: "consent",            // force the consent screen
  loginHint: "sam@acme.com",    // pre-fill the account chooser
});

handleCallback(code) returns { user, created, profile }, where profile is the raw Google userinfo (sub, email, name, picture, …) in case you want extra fields.

How merging works

Google emails are verified, so handleCallback merges by email: if a user with that address already exists (from any method), the Google identity is linked to that same account. A user who used an email code last week and Google today is one user, not two. → Merge-by-email

Next steps

On this page