🔐 OAuth ドライバー
OAuth ドライバーは、Passport.js を使用してサードパーティ OAuth プロバイダーを統合するための一貫したレイヤーを提供します。プロバイダー戦略のセットアップをカプセル化し、ルートおよび機能へ合成する Promise ベースの request と callback ヘルパーを公開します。
🎯 概要
NodeBlocks の OAuth ドライバーは、Google、Twitter、LINE 用 Passport.js 戦略の薄いラッパーです。各ファクトリーは同期的であり、await は不要です。
import { drivers } from '@nodeblocks/backend-sdk';
const {
createGoogleOAuthDriver,
createTwitterOAuthDriver,
createLineOAuthDriver,
verifyGoogleCallback,
verifyTwitterCallback,
verifyLineCallback,
PROVIDER_GOOGLE,
PROVIDER_TWITTER,
PROVIDER_LINE,
TWITTER_CALLBACK_STATE_SESSION_KEY,
} = drivers;
各ファクトリーは 3 つのメソッドを持つドライバーオブジェクトを返します。
| メソッド | 目的 |
|---|---|
initialize(app) | Express アプリに Passport と必要なミドルウェアを登録します。 |
request(req, res, state) | OAuth 認可フローを開始します。 |
callback(req, res) | OAuth コールバックを処理し、正規化済みプロファイルを返します。 |
ドライバー定数:
| エクスポート | 値 | ソースファイル |
|---|---|---|
PROVIDER_GOOGLE | 'google' | src/drivers/oauth/google.ts |
PROVIDER_TWITTER | 'twitter' | src/drivers/oauth/twitter/index.ts |
PROVIDER_LINE | 'line' | src/drivers/oauth/line/index.ts |
TWITTER_CALLBACK_STATE_SESSION_KEY | 'twitter-callback-state' | src/drivers/oauth/twitter/index.ts |
グローバル副作用: 各ファクトリーは共有 Passport シングルトンに対して
passport.use(new ...Strategy(...))を呼び出します。複数のファクトリー関数を呼び出すと、プロセス内の同じ Passport インスタンスに戦略が登録されます。
型 — ドライバーインターフェースおよびプロファイル型は types 名前空間にあります(SDK ソース: src/types/oauth.ts)。
import { types } from '@nodeblocks/backend-sdk';
type GoogleOAuthDriver = types.GoogleOAuthDriver;
type GoogleProfile = types.GoogleProfile;
type TwitterOAuthDriver = types.TwitterOAuthDriver;
type TwitterProfile = types.TwitterProfile;
type TwitterCallbackState = types.TwitterCallbackState;
type TwitterRequest = types.TwitterRequest;
type LineOAuthDriver = types.LineOAuthDriver;
type LineProfile = types.LineProfile;
// OAUTH_LOGIN, OAUTH_SIGNUP, OAuthLoginState, ...
コールバック URL: OAuth プロバイダーのコンソールで同じリダイレクト URI を登録し、ドライバーファクトリーに渡してください。SDK の OAuth ルートは
/auth/oauth/{provider}/callback(例:/auth/oauth/google/callback)を使用します。callbackURLはプロバイダー登録と、認証サービスでマウントするルートパスの両方に一致する必要があります。
📋 利用可能な OAuth ドライバー
Google OAuth ドライバー
Passport.js の Google OAuth 2.0 戦略(passport-google-oauth20)を統合します。
createGoogleOAuthDriver
| パラメーター | 型 | デフォルト | 説明 |
|---|---|---|---|
clientID | string | — | Google OAuth クライアント ID |
clientSecret | string | — | Google OAuth クライアントシークレット |
callbackURL | string | — | OAuth 完了後のリダイレクト URL |
scope | string[] | ['email', 'profile'] | OAuth スコープ |
verify | typeof verifyGoogleCallback | verifyGoogleCallback | 任意の検証関数 |
戻り値: GoogleOAuthDriver
const googleDriver = createGoogleOAuthDriver(
process.env.GOOGLE_CLIENT_ID!,
process.env.GOOGLE_CLIENT_SECRET!,
'https://app.com/auth/oauth/google/callback'
);
googleDriver.initialize(app);
Google ドライバーメソッド
戦略は passReqToCallback: true を使用します。カスタム検証関数は第 1 引数として req を受け取ります(デフォルトの verifyGoogleCallback はこれを無視します)。
| メソッド | シグネチャ | 戻り値 |
|---|---|---|
initialize | (app: Express) => void | passport.initialize() を登録します。 |
request | (req, res, state: string) => Promise<void> | { prompt: 'consent', state } で OAuth を開始します。 |
callback | (req, res) => Promise<GoogleProfile> | session: false を指定した { displayName, email, id }。 |
Twitter OAuth ドライバー
レガシーの passport-twitter パッケージではなく、PKCE を備えたカスタム OAuth 2.0 戦略です。
createTwitterOAuthDriver
| パラメーター | 型 | デフォルト | 説明 |
|---|---|---|---|
clientID | string | — | Twitter アプリケーションの App ID |
clientSecret | string | — | Twitter アプリケーションの App Secret |
callbackURL | string | — | Twitter OAuth 用コールバック URL |
sessionSecret | string | — | express-session 用シークレット |
verify | VerifyFunctionWithRequest | verifyTwitterCallback | 任意の検証関数 |
戻り値: TwitterOAuthDriver
セッションミドルウェア(initialize が ['/auth/oauth/twitter', '/auth/oauth/twitter/callback'] に登録):
| 設定 | 値 |
|---|---|
resave | false |
saveUninitialized | false |
| Cookie | httpOnly、sameSite: 'lax'、secure: 'auto'、maxAge: 10 minutes |
戦略のデフォルト(TwitterStrategy に組み込み。ファクトリーからは設定不可):
| 設定 | 値 |
|---|---|
| スコープ | ['users.read', 'tweet.read'] |
| PKCE | true |
| 認可 URL | https://twitter.com/i/oauth2/authorize |
| トークン URL | https://api.twitter.com/2/oauth2/token |
| プロファイル URL | https://api.twitter.com/2/users/me |
const twitterDriver = createTwitterOAuthDriver(
process.env.TWITTER_CLIENT_ID!,
process.env.TWITTER_CLIENT_SECRET!,
'https://app.com/auth/oauth/twitter/callback',
process.env.SESSION_SECRET!
);
twitterDriver.initialize(app);
Twitter ドライバーメソッド
| メソッド | シグネチャ | 戻り値 |
|---|---|---|
initialize | (app: Express) => void | Twitter ルートにセッションミドルウェアを設定してから passport.initialize() を登録します。 |
request | (req: TwitterRequest, res, state: TwitterCallbackState) => Promise<void> | state を req.session[TWITTER_CALLBACK_STATE_SESSION_KEY] に保存し、OAuth を開始します。 |
callback | (req: TwitterRequest, res) => Promise<{ state: TwitterCallbackState; user: TwitterProfile }> | セッション状態とユーザープロファイル。 |
TwitterCallbackState の形状: { typeId, redirectUrl, purpose }。purpose の値は types.OAUTH_LOGIN / types.OAUTH_SIGNUP と対応します。
コールバックエラー:
| 条件 | エラー |
|---|---|
| Passport がユーザーを返さない | Passport の status/info を持つ AuthenticationOAuthError |
| セッション状態がない | AuthenticationOAuthError: 'Twitter OAuth authentication failed. Session state required for executing callback not found.' |
成功時、callback は常に { state, user } を返します。state は実行時に必須です(TypeScript の戻り値型では任意ですが、実装は存在しない場合に拒否します)。
LINE OAuth ドライバー
LINE Login 用のカスタム OAuth 2.0 戦略です。
createLineOAuthDriver
| パラメーター | 型 | デフォルト | 説明 |
|---|---|---|---|
clientID | string | — | LINE チャネル ID |
clientSecret | string | — | LINE チャネルシークレット |
callbackURL | string | — | OAuth 完了後のリダイレクト URL |
scope | string[] | ['profile', 'openid', 'email'] | OAuth スコープ(戦略のデフォルトを上書き) |
verify | VerifyFunctionWithRequest | verifyLineCallback | 任意の検証関数 |
戻り値: LineOAuthDriver
戦略のデフォルト(LineStrategy に組み込み):
| 設定 | 値 |
|---|---|
| 認可 URL | https://access.line.me/oauth2/v2.1/authorize |
| トークン URL | https://api.line.me/oauth2/v2.1/token |
| プロファイル URL | https://api.line.me/oauth2/v2.1/userinfo |
| 組み込みスコープ(ファクトリー上書き前) | ['openid'] |
ファクトリーの scope パラメーターは組み込みデフォルトを上書きします。
const lineDriver = createLineOAuthDriver(
process.env.LINE_CHANNEL_ID!,
process.env.LINE_CHANNEL_SECRET!,
'https://app.com/auth/oauth/line/callback'
);
lineDriver.initialize(app);
LINE ドライバーメソッド
| メソッド | シグネチャ | 戻り値 |
|---|---|---|
initialize | (app: Express) => void | passport.initialize() を登録します。 |
request | (req, res, state: string) => Promise<void> | { session: false, state } で OAuth を開始します。 |
callback | (req, res) => Promise<LineProfile> | session: false を指定した { name, sub }。 |
型と実装:
src/types/oauth.tsのLineOAuthDriver.requestは任意のscopeパラメーターを含むLineRequestAuthentication型ですが、ドライバー実装が受け取るのは(req, res, state)のみです。
コールバックエラー: Passport がユーザーを返さない場合、callback は Passport の status/info を含む AuthenticationOAuthError で拒否します。検証失敗も、返される Promise を拒否します。
カスタム検証関数
各ファクトリーは任意の verify パラメーターを受け取ります(デフォルト値は上記のファクトリー表を参照)。デフォルト検証関数は drivers 名前空間からエクスポートされます。
const { verifyGoogleCallback, verifyTwitterCallback, verifyLineCallback } = drivers;
verifyGoogleCallback
profile.emails[0].value と profile.id を検証してから、{ displayName, email, id } を Passport に渡します。Google が省略する場合、実行時の displayName は undefined になる可能性があります。検証されるのは email と id のみです。必須データがない場合、メッセージ 'Google oauth payload error' の AuthenticationBadRequestError が発生します。
verifyTwitterCallback
profile、profile.id、profile.username を検証してから、{ displayName: profile.name, id, username } を Passport に渡します。Twitter が name を省略する場合、実行時の displayName は undefined になる可能性があります。データがない場合は AuthenticationOAuthError が発生します。
verifyLineCallback
profile.sub を検証してから、{ name: profile?.name, sub } を Passport に渡します。LINE が省略する場合、name は実行時に undefined になる可能性があります。カスタム検証関数は内部戦略(src/drivers/oauth/line/strategy.ts)からの LineUserInfoPayload を受け取ります。これは drivers からエクスポートされません。sub がない場合、メッセージ 'Cannot get sub from line oauth payload' の AuthenticationOAuthError が発生します。
検証失敗時は Passport の done(error) が呼ばれ、ドライバー callback の Promise は拒否します。
🔧 OAuth ドライバーの使用
サービスとともに使用する
ドライバーを作成し、それぞれで initialize(app) を呼び出してから、authService の第 3 引数オプションで注入します。
import { services, drivers } from '@nodeblocks/backend-sdk';
const { authService } = services;
const {
createGoogleOAuthDriver,
createTwitterOAuthDriver,
createLineOAuthDriver,
} = drivers;
const googleOAuthDriver = createGoogleOAuthDriver(
process.env.GOOGLE_CLIENT_ID!,
process.env.GOOGLE_CLIENT_SECRET!,
'https://app.com/auth/oauth/google/callback'
);
const twitterOAuthDriver = createTwitterOAuthDriver(
process.env.TWITTER_CLIENT_ID!,
process.env.TWITTER_CLIENT_SECRET!,
'https://app.com/auth/oauth/twitter/callback',
process.env.SESSION_SECRET!
);
const lineOAuthDriver = createLineOAuthDriver(
process.env.LINE_CHANNEL_ID!,
process.env.LINE_CHANNEL_SECRET!,
'https://app.com/auth/oauth/line/callback'
);
googleOAuthDriver.initialize(app);
twitterOAuthDriver.initialize(app);
lineOAuthDriver.initialize(app);
authService(
dataStores,
{
authSecrets: {
authEncSecret: process.env.AUTH_ENC_SECRET!,
authSignSecret: process.env.AUTH_SIGN_SECRET!,
},
},
{ googleOAuthDriver, twitterOAuthDriver, lineOAuthDriver }
);
完全な Express 接続、データストア、セッション/Cookie セットアップ、OAuth 環境変数、その他の第 3 引数オプション(mailService など)については、認証サービスを参照してください。
🔗 関連ドキュメント
- ドライバー概要 — ドライバーの完全なエクスポート一覧
- OAuth ブロック — OAuth フローのビジネスロジック
- OAuth ルート — OAuth 用 HTTP ルート合成
- 認証サービス — OAuth ドライバー向けサービス接続