express-oauth2-jwt-bearer について
Node.jsのExpress APIにAuth0のJWT Bearer検証ミドルウェアを導入するためのスキルです。署名、audience、issuer、有効期限を検証し、scopeやクレームに基づくルート制御も扱います。
主な機能
- 01Bearer JWTの検証
- 02署名、audience、issuerの確認
- 03トークン有効期限の確認
- 04scopeによるアクセス制限
- 05クレームに基づく認可
活用シーン
- 01Express APIルートの保護
- 02SPAやモバイルアプリのアクセストークン検証
- 03scopeによるAPI権限の制御
- 04トークンクレームに基づくリクエスト制限
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ auth0/ agent-skills --skill express-oauth2-jwt-bearerインストール後、Claude Code で/express-oauth2-jwt-bearerを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
references/api.mdintegration.mdsetup.mdscripts/bootstrap.mjspackage.jsonscripts/utils/apis.mjsauth0-api.mjschange-plan.mjsdiscovery.mjsenv-writer.mjshelpers.mjsvalidation.mjstests/evals.jsongraders.jsonprompt.md詳細
Node OAuth2 JWT Bearer 統合
express-oauth2-jwt-bearer パッケージは、Auth0 JWT Bearer アクセストークンを検証する Express ミドルウェアを提供します。RFC 6750 に従って、トークンの抽出、署名の検証、オーディエンスと発行者の検証、有効期限の確認を行うため、JWT の解析ではなくビジネスロジックに集中できます。
エージェントへの指示: SDK のセットアップ手順を案内する前に、次のコマンドを実行して最新のリリースバージョンを取得してください。
gh api repos/auth0/node-oauth2-jwt-bearer/releases/latest --jq '.tag_name'取得したバージョンを、以下にハードコードされているバージョンの代わりに、すべての
package.jsonの依存関係の行で使用してください。
前提条件
- Node.js 18 以上(20 以上を推奨。ブートストラップスクリプトの自動化に必要です)
- Express 4.x または 5.x
- npm または yarn
- API(リソースサーバー)が設定済みの Auth0 アカウント
- Auth0 CLI(自動セットアップ用):
npm install -g @auth0/auth0-cli
使用しないケース
| ユースケース | 推奨スキル |
|---|---|
| ログイン UI(Express セッション)を備えたサーバーサイド Web アプリの構築 | auth0-express |
| サーバーサイド認証を備えた Next.js アプリの構築 | auth0-nextjs |
| React/Angular/Vue の SPA の構築 | auth0-react、auth0-angular、auth0-vue |
| React Native またはモバイルアプリの構築 | auth0-react-native、auth0-android、auth0-swift |
| ASP.NET Core Web API | auth0-aspnetcore-api |
| JWT ミドルウェアを使用する Go API | go-jwt-middleware |
| Python API(Flask/FastAPI) | auth0-api-python |
古い express-jwt パッケージを使用する Node.js API | express-jwt |
クイックスタートのワークフロー
エージェントへの指示: 以下の手順に従って、ユーザーの Node.js API プロジェクトに
express-oauth2-jwt-bearerを統合してください。
最新バージョンを取得する(上記の指示を参照してください)。
SDK をインストールする:
npm install express-oauth2-jwt-bearerAuth0 を設定する —
references/setup.mdに従ってください。ユーザーがプロンプト内ですでに Auth0 ドメインと API オーディエンスを指定している場合は、.envファイルにISSUER_BASE_URL(https://を含む発行者の完全な URL)とAUDIENCEとして記述してください。SDK がこれらを自動的に読み取ります。ブートストラップスクリプトはスキップし、再確認のためにAskUserQuestionを呼び出さないでください。ドメインやオーディエンスをserver.js/app.jsにリテラル文字列(または||によるフォールバックのデフォルト値)としてハードコードしないでください — これらは.envのみに記述します。それ以外の場合は、ブートストラップスクリプトによる自動セットアップか、手動セットアップを提案してください。ミドルウェアをセットアップする — まず Auth0 の値を含む
.envファイルを作成し、その後、値を読み込んでミドルウェアを追加します。express-oauth2-jwt-bearerは環境からISSUER_BASE_URLとAUDIENCEを自動的に読み取るため、auth()に引数は不要です:# .env ISSUER_BASE_URL=https://your-tenant.us.auth0.com AUDIENCE=https://your-api-identifierimport 'dotenv/config'; // SDK が process.env を読み取る前に .env を読み込む import { auth } from 'express-oauth2-jwt-bearer'; // 環境から ISSUER_BASE_URL と AUDIENCE を読み取るため、設定は不要 const checkJwt = auth(); app.use(checkJwt); // グローバルまたはルートごとに適用発行者とオーディエンスは
.envに記述してください — ここにリテラル値を直接記述したり、引数として渡したりしないでください。エンドポイントを保護する — ミドルウェアをグローバルまたは特定のルートに適用します:
// グローバルに保護 app.use(checkJwt); // またはルートごとに保護 app.get('/api/private', checkJwt, (req, res) => { res.json({ sub: req.auth.payload.sub }); });RBAC を追加する(任意) — 権限ベースのアクセス制御には
requiredScopes()またはclaimIncludes()を使用します:import { auth, requiredScopes, claimIncludes } from 'express-oauth2-jwt-bearer'; app.get('/api/messages', checkJwt, requiredScopes('read:messages'), (req, res) => { res.json({ messages: [] }); });重要:
requiredScopesが受け取る引数は 1 つです — スペース区切りの文字列または配列です。複数の文字列引数を渡さないでください:requiredScopes('read:msg', 'write:msg')は、最初の引数以降をすべて無視します。代わりにrequiredScopes('read:msg write:msg')またはrequiredScopes(['read:msg', 'write:msg'])を使用してください。統合を検証する — ビルドしてテストします:
node server.js curl http://localhost:3000/api/private # 401 が返るはずです curl -H "Authorization: Bearer <token>" http://localhost:3000/api/private # 200 が返るはずです失敗時の確認: サーバーが起動しない場合や、予期せずトークンが拒否される場合は、よくある問題について
references/api.mdを確認してください。5~6 回試しても失敗する場合は、AskUserQuestionを使ってユーザーに環境の詳細を尋ねてください。
詳細なドキュメント
- セットアップガイド — Auth0 API の登録、.env の設定、自動セットアップ用ブートストラップスクリプト、シークレット管理
- 統合パターン — 保護されたエンドポイント、スコープとクレームによる RBAC、DPoP、CORS のセットアップ、エラー処理、curl によるテスト
- API リファレンスとテスト — 設定オプションの全一覧、クレームのリファレンス、完全なコード例、テストチェックリスト、よくある問題
よくある間違い
| 間違い | 症状 | 修正方法 |
|---|---|---|
| Auth0 Dashboard で API ではなく Application を作成した | トークンの検証に失敗する。Audience が正しくない | Auth0 Dashboard → APIs で新しい API(Resource Server)を作成します |
| Audience が API identifier と完全に一致していない | 401 Unauthorized — 「Audience mismatch」 | Auth0 Dashboard → APIs から API Identifier の文字列をそのままコピーします |
ISSUER_BASE_URL に https:// スキームが含まれていない | 起動時に Error: Invalid URL | ISSUER_BASE_URL は完全な Issuer URL にする必要があります:https://your-tenant.us.auth0.com |
RBAC で permissions ではなく scope クレームを確認している | 常に 403 が返される、または権限が無視される | スコープベースの RBAC には requiredScopes() を使用します。Auth0 RBAC の権限クレームには claimIncludes('permissions', 'read:data') を使用します |
| 認証ミドルウェアより前に CORS が設定されていない | プリフライトの OPTIONS リクエストが 401 を返す | ミドルウェアチェーンで auth() の前に cors() ミドルウェアを追加します |
.env ファイルが読み込まれていない | ドメイン/Audience が undefined になる | エントリーファイルの先頭に import 'dotenv/config' を追加します |
ソース内でドメイン/Audience をハードコードしている(process.env.X || 'literal' のフォールバックを含む) | シークレットがソースにコミットされる。セキュリティレビューに通らない | 値を .env(ISSUER_BASE_URL/AUDIENCE)に設定し、auth() が自動的に読み込むようにします。リテラルのフォールバックは使用しません |
req.auth が undefined になっている | TypeError: Cannot read properties of undefined | checkJwt ミドルウェアがハンドラーより前に実行されることを確認します |
関連スキル
- auth0-express — ログイン UI(セッション、Cookie)を備えた Express ウェブアプリ向け
- auth0-nextjs — Next.js のサーバーサイドウェブアプリ向け
- auth0-aspnetcore-api — .NET 向け BACKEND_API リファレンス実装
- go-jwt-middleware — Go API 向け JWT ミドルウェア
- auth0-api-python — Python API 向け JWT 検証(Flask/FastAPI)
- auth0-cli — ターミナルから Auth0 リソースを管理
クイックリファレンス
コアミドルウェア
| 関数 | 説明 | 戻り値 |
|---|---|---|
auth(options?) | JWT Bearer 検証ミドルウェア | Handler — トークンが無効または存在しない場合は 401 |
requiredScopes(scopes) | トークンに必要なスコープがすべて含まれていることを検証 | Handler — スコープが不足している場合は 403 |
scopeIncludesAny(scopes) | トークンに少なくとも 1 つのスコープが含まれていることを検証 | Handler — 一致するスコープがない場合は 403 |
claimEquals(claim, value) | クレームが値と一致することを検証 | Handler — 一致しない場合は 401 |
claimIncludes(claim, ...values) | クレームにすべての値が含まれていることを検証 | Handler — 不完全な場合は 401 |
claimCheck(fn, desc?) | カスタムクレーム検証関数 | Handler — fn が false を返す場合は 401 |
設定オプション
| オプション | 型 | 説明 |
|---|---|---|
issuerBaseURL | string | https:// を含む完全な Issuer URL。省略可 — デフォルトでは ISSUER_BASE_URL 環境変数を使用 |
audience | string | Auth0 Dashboard の API Identifier。省略可 — デフォルトでは AUDIENCE 環境変数を使用 |
tokenSigningAlg | string | 署名アルゴリズム(デフォルト:RS256。対称鍵方式では HS256 を使用) |
authRequired | boolean | 認証を任意にするには false を設定(デフォルト:true) |
clockTolerance | number | クロックスキューの許容秒数(デフォルトなし。設定しない場合は undefined) |
dpop | DPoPOptions | DPoP の設定(integration.md を参照) |
環境変数
| 変数 | 説明 |
|---|---|
ISSUER_BASE_URL | https:// を含む完全な Issuer URL。例:https://your-tenant.us.auth0.com(SDK が自動検出) |
AUDIENCE | API Identifier。例:https://your-api-identifier(SDK が自動検出) |
リクエストオブジェクト
検証に成功すると、req.auth に次の内容が含まれます:
req.auth.payload // Decoded JWT payload (sub, iss, aud, exp, permissions, etc.)
req.auth.header // JWT header (alg, typ, kid)
req.auth.token // Raw JWT string
SDK アーキテクチャ
node-oauth2-jwt-bearer モノレポには、3 つのパッケージが含まれています。
| パッケージ | 用途 |
|---|---|
express-oauth2-jwt-bearer | メインパッケージ。 JWT Bearer 検証用の Express ミドルウェアです。npm に公開されています。 |
access-token-jwt | 低レベルの JWT 検証ユーティリティです(内部で使用)。 |
oauth2-bearer | RFC 6750 に基づく Bearer トークン抽出機能です(内部で使用)。 |
実際には、インストールしてインポートするのは express-oauth2-jwt-bearer だけです。
認証フローの比較
| 認証パターン | SDK | 使用する場面 |
|---|---|---|
| JWT Bearer(ステートレス) | express-oauth2-jwt-bearer | SPA、モバイルアプリ、M2M クライアントから呼び出される API |
| セッションベース(ステートフル) | @auth0/express-openid-connect | ログイン UI とサーバーサイドセッションを備えた Web アプリ |
テストのクイックリファレンス
# Get test token from Auth0 Dashboard → APIs → your API → Test tab
# Copy the token, then:
# 1. Verify 401 on protected route (no token)
curl -v http://localhost:3000/api/private
# 2. Verify 200 with valid token
curl -H "Authorization: Bearer <paste-token-here>" http://localhost:3000/api/private
# 3. Verify 403 with valid token but missing scope
curl -H "Authorization: Bearer <paste-token-here>" http://localhost:3000/api/admin
# 4. Verify CORS preflight
curl -v -X OPTIONS http://localhost:3000/api/private \
-H "Origin: http://localhost:5173" \
-H "Access-Control-Request-Method: GET" \
-H "Access-Control-Request-Headers: Authorization"