🔗 OAuth
OAuth provides public browser initiation and callback routes for Google, LINE, and Twitter; it is composed by authService, not a standalone OAuth service.
Start here
Create each provider driver, register its middleware on the Express app, then mount authService. The callback URLs registered with a provider must include the same mount prefix as the SDK route: /auth/oauth/google/callback, /auth/oauth/line/callback, or /auth/oauth/twitter/callback. Use the root mount below when enabling Twitter: its driver installs session middleware only for the unprefixed Twitter SDK paths.
import express from 'express';
import {drivers, services} from '@nodeblocks/backend-sdk';
const app = express();
const googleOAuthDriver = drivers.createGoogleOAuthDriver(
'google-client-id',
'google-client-secret',
'https://app.example.test/auth/oauth/google/callback',
);
const twitterOAuthDriver = drivers.createTwitterOAuthDriver(
'twitter-client-id',
'twitter-client-secret',
'https://app.example.test/auth/oauth/twitter/callback',
'replace-with-a-session-secret',
);
const lineOAuthDriver = drivers.createLineOAuthDriver(
'line-client-id',
'line-client-secret',
'https://app.example.test/auth/oauth/line/callback',
);
twitterOAuthDriver.initialize(app);
googleOAuthDriver.initialize(app);
lineOAuthDriver.initialize(app);
app.use(
'/',
services.authService(
{identities, refreshtokens, onetimetokens},
{authSecrets: {authEncSecret: 'replace-me', authSignSecret: 'replace-me'}},
{googleOAuthDriver, twitterOAuthDriver, lineOAuthDriver},
),
);
| Configuration | Default / source behavior | Effect |
|---|---|---|
dataStores.identities | Required for every callback | Finds provider identities and creates one for oauth-signup. |
dataStores.refreshtokens | Required for authService | Stores generated refresh tokens. |
dataStores.onetimetokens | Required for every callback | Stores the generated login one-time token. |
configuration.authSecrets | Required for initiation and callback | Signs provider state and verifies it on Google/LINE callbacks; signs the final one-time token. |
configuration.onetimeTokenSignOptions | Passed to provider-state or final login-token generation; authService defaults to { expiresIn: '5m' } | Controls one-time-token lifetime. |
| Provider driver | Required for its two routes | Supplies request and callback; call its initialize(app) before requests. |
Google and LINE initiation state includes fp, purpose, redirectUrl, optional typeId, and user agent. Twitter passes { purpose, redirectUrl, typeId } to its driver, which maintains provider callback state. The SDK does not validate callback queries with a schema even though stateQueryParameter is exported.
Common tasks
| Task | Start with | Contract |
|---|---|---|
| Start Google login or signup | googleOAuthFeature | Public googleOAuthFeature and googleOAuthRoute; query values follow googleOauthSchema |
| Start LINE login or signup | lineOAuthFeature | Public lineOAuthFeature and lineOAuthRoute; query values follow lineOauthSchema |
| Start Twitter login or signup | twitterOAuthFeature | Public twitterOAuthFeature and twitterOAuthRoute; query values follow twitterOauthSchema |
| Handle a provider return | OAuth callback features | The corresponding public callback feature/route redirects to the supplied redirectUrl with ?onetimeToken=<token> |
Browser workflow
Navigate to GET /auth/oauth/google?fp=device-fingerprint&purpose=oauth-login&redirectUrl=https%3A%2F%2Fclient.example.test%2Foauth%2Fcomplete. The Google driver redirects the browser to Google. For oauth-signup, provide typeId; it is optional at schema level but identity creation rejects an absent value with 400.
After provider authentication, Google and LINE receive state; Twitter receives driver-managed callback state. A callback resolves or creates the identity, stores a one-time login token, and issues a 302 redirect to the decoded redirectUrl with onetimeToken appended. The redirect helper always appends ?onetimeToken=, so callers must provide a redirect URL whose query-string behavior they accept.
Custom feature composition
The service is the normal integration point. A custom host must pass the same stores, configuration, and provider driver in its composition context; a feature is an SDK composer, not Express middleware.
import {partial} from 'ramda';
import {features, primitives} from '@nodeblocks/backend-sdk';
const router = primitives.defService(
partial(primitives.compose(features.googleOAuthFeature, features.googleOAuthCallbackFeature), [
{configuration, dataStores: {identities, onetimetokens}, googleOAuthDriver},
]),
);
app.use('/', router);
Reference map
| Page | Purpose |
|---|---|
| Blocks | Provider-state, token, fingerprint, and redirect helpers. |
| Features | Schema-to-route OAuth compositions. |
| Routes | Public initiation and callback endpoint contracts. |
| Schemas | Provider initiation query validation. |
OAuth has no handlers.md or validators.md page; it composes through Authentication.
Related modules
Authentication provides the containing service and one-time-token login. Authentication service defines configuration and mounting. OAuth drivers define Google, Twitter, and LINE driver factories and middleware. Authentication blocks provide token, fingerprint, and identity helpers; common blocks provide the final redirect.