Documentation

SSO

Google

Add Google sign-in to VitNode. Create an OAuth client, set the exact redirect URI and register the Google SSO adapter in your API config.

Google is the provider most people want first. You create an OAuth client in the Google Auth Platform, give it the redirect URI VitNode already decided on, and pass the two credentials to GoogleSSOApiPlugin. That's the whole job.

Before you begin

Set up the OAuth client

Sign in to Google Cloud

Go to the Google Cloud Console and sign in with the account that should own the OAuth client. It does not have to be the account you sign in to your own site with.

Pick or create a project

An OAuth client belongs to a project, so select one from the project picker in the top bar, or create one if this is a fresh account. Name it after your site; the name is internal and never shown to visitors.

Open the Google Auth Platform

Type Google Auth Platform into the console's search bar and open the first result. This is the section that used to be called "OAuth consent screen", and it is where both the consent details and the clients live.

Google will not issue a client until it knows what to show on the consent screen. Provide the App name and a Support email. Google shows the app name on the consent screen only after your app is verified; until then visitors see your domain.

Then, under Audience, choose External so anyone with a Google account can sign in. Internal restricts sign-in to a single Google Workspace organization, which is almost never what a public site wants.

Create the client and set the redirect URI

Go to Clients in the left navigation and press Create client.

  1. Application type: Web application.
  2. Name: anything you like. This one is internal too.
  3. Under Authorized redirect URIs, add the URI for every origin you run.

VitNode builds this URI itself, from VITNODE_WEB_URL, so it has to match character for character, with no trailing slash and no locale prefix.

EnvironmentAuthorized redirect URI
Development (VITNODE_WEB_URL unset)http://localhost:3000/login/sso/google
Productionhttps://your-domain.com/login/sso/google

Add both. Google allows several redirect URIs per client, and one client for dev and prod is fine while you are getting started.

redirect_uri_mismatch

This is the error you will get if the URI differs by so much as a trailing slash. It comes from Google, not from VitNode, and it is always this field.

Copy the client ID and secret

Google shows the full Client secret only once, when the client is created. Copy it and the Client ID straight into the API's .env. Later the console shows only the secret's last four characters; if you lose it, add a new secret to the client and delete the old one.

Changes to the redirect URIs can take from 5 minutes to a few hours to apply.

Set the environment variables

These names are not magic. They are whatever you read in your config on the next step. What matters is that they are server-side variables, so leave them out of clientEnv. That list is what publishes a value to the browser bundle, and a client secret in the browser bundle is a client secret you have published.

.env
GOOGLE_CLIENT_ID=1234567890-abc.apps.googleusercontent.com
GOOGLE_CLIENT_SECRET=GOCSPX-xxxxxxxxxxxxxxxx

Add the adapter

Add GoogleSSOApiPlugin to authorization.ssoAdapters in the API's vitnode.api.config.ts (where it lives), next to any adapters you already have. Keep the rest of the config as it is:

src/vitnode.api.config.ts (excerpt)
import { GoogleSSOApiPlugin } from '@vitnode/core/api/adapters/sso/google'
import { buildApiConfig } from '@vitnode/core/vitnode.config'

export const vitNodeApiConfig = buildApiConfig({
  // ...
  authorization: {
    ssoAdapters: [
      // ...
      GoogleSSOApiPlugin({
        clientId: process.env.GOOGLE_CLIENT_ID,
        clientSecret: process.env.GOOGLE_CLIENT_SECRET,
      }),
    ],
  },
})

No authorization block yet? Create one with just ssoAdapters, as in the SSO setup. Then restart the dev server, since .env and the API config are only read at start-up.

Check the result

Open /login in a private window and press the Google button under Continue with. You should be sent to Google's consent screen, bounced back to /login/sso/google?code=...&state=..., and land on the front page signed in. Your account now has a row in core_users_sso with providerId google.

Publish the app

While the app's publishing status is Testing, Google normally limits sign-in to the test users you listed. The adapter asks only for openid profile email, which Google exempts, so any Google account can sign in without the unverified-app warning. Publish anyway once the round trip works, so the app is ready for production. Go to Google Auth Platform → Audience and press Publish app.

What the adapter asks Google for

Useful when you are debugging a consent screen that shows more or fewer permissions than you expected.

SettingValue
Authorize URLhttps://accounts.google.com/o/oauth2/auth
Token URLhttps://oauth2.googleapis.com/token
Profile URLhttps://www.googleapis.com/oauth2/v1/userinfo
Scopesopenid profile email
Provider idgoogle
Fields readid, email, name, verified_email, given_name, family_name, picture

The account name VitNode creates comes from Google's name field, stripped of characters that cannot appear in a profile URL.

given_name, family_name and picture come with the profile scope Google already asks for, so Connected accounts can import all three with no extra permission. Google never guarantees them, and an account without one has nothing to import for that field.

Gotchas

Unverified Google emails are rejected

The adapter reads verified_email and throws a 400 when it is false, so a Google account with an unconfirmed address cannot sign in at all. The visitor sees the generic error screen rather than an explanation, which is the one place this is worth knowing about in advance.

A missing key fails on click, not on boot

A GoogleSSOApiPlugin whose clientId is undefined registers happily. The button renders, the provider is listed, and it throws Missing Google client ID the moment somebody presses it. If the button is there but does nothing except raise an error toast, check the environment before you check the console.

An email that already has an account

If someone already registered with the same address, by password or through another provider, the callback asks for that account's password and then links the two. See how accounts link.