SSO
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
- A running VitNode app. This page covers only the Google parts; SSO setup explains the shared steps and where the API's
.envand config live.
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.
Fill in the consent details
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.
- Application type: Web application.
- Name: anything you like. This one is internal too.
- 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.
| Environment | Authorized redirect URI |
|---|---|
Development (VITNODE_WEB_URL unset) | http://localhost:3000/login/sso/google |
| Production | https://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.
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.
GOOGLE_CLIENT_ID=1234567890-abc.apps.googleusercontent.com
GOOGLE_CLIENT_SECRET=GOCSPX-xxxxxxxxxxxxxxxxAdd 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:
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.
| Setting | Value |
|---|---|
| Authorize URL | https://accounts.google.com/o/oauth2/auth |
| Token URL | https://oauth2.googleapis.com/token |
| Profile URL | https://www.googleapis.com/oauth2/v1/userinfo |
| Scopes | openid profile email |
| Provider id | google |
| Fields read | id, 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
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 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.
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.