Auth0 Next.js SDK は、Next.js アプリケーションにユーザー認証を実装するためのライブラリです。
ドキュメント - はじめに - API リファレンス - フィードバック
QuickStart - Next.js アプリに Auth0 を追加するためのガイド。
FAQ - nextjs-auth0 に関するよくある質問。
例 - さまざまな使用例に対応した多数の例。
セキュリティ - 確認する必要があるいくつかの重要なセキュリティ通知。
アーキテクチャ - SDK のアーキテクチャの概要。
テスト - nextjs-auth0 アプリケーションのテストに役立ちます。
デプロイ - サンプル アプリを Vercel にデプロイする方法。
ドキュメント サイト - ドキュメント サイトを参照して、Auth0 について詳しく学習してください。
npm の使用:
npm install @auth0/nextjs-auth0
このライブラリには、Node.js 16 LTS 以降の LTS バージョンが必要です。
Auth0 ダッシュボードで通常の Web アプリケーションを作成します。
既存のアプリケーションを使用している場合は、通常の Web アプリケーションで次の設定が構成されていることを確認してください。
アプリケーションのページの「設定」タブをクリックします。
下にスクロールして「詳細設定を表示」リンクをクリックします。
「詳細設定」で「OAuth」タブをクリックします。
「JsonWebToken Signature Algorithm」が
RS256
に設定され、「OIDC Conformant」が有効になっていることを確認します。
次に、[設定] ページの [アプリケーション URI] セクションで、アプリケーションの次の URL を構成します。
許可されるコールバック URL : http://localhost:3000/api/auth/callback
許可されるログアウト URL : http://localhost:3000/
「基本情報」セクションのクライアント ID 、クライアント シークレット、およびドメインの値をメモします。これらの値は次のステップで必要になります。
Next.js アプリケーションが Auth0 と適切に通信できるようにする必要があります。これを行うには、ルート プロジェクト ディレクトリの下に.env.local
ファイルを作成し、次のように必要な Auth0 構成値を定義します。
# セッションの暗号化に使用される長い秘密の値 cookieAUTH0_SECRET='LONG_RANDOM_VALUE'# アプリケーションのベース URLAUTH0_BASE_URL='http://localhost:3000'# Auth0 テナントの URL ドメインAUTH0_ISSUER_BASE_URL='https://YOUR_AUTH0_DOMAIN.auth0 .com'# Auth0 アプリケーションのクライアントIDAUTH0_CLIENT_ID='YOUR_AUTH0_CLIENT_ID'# Auth0 アプリケーションのクライアント シークレットAUTH0_CLIENT_SECRET='YOUR_AUTH0_CLIENT_SECRET'
次のコマンドを実行して、 AUTH0_SECRET
値に適切な文字列を生成できます。
ノード -e "console.log(crypto.randomBytes(32).toString('hex'))"
Auth0 構成オプションの完全なリストは、「モジュール構成」ドキュメントの「構成プロパティ」セクションで確認できます。
Next.js での環境変数の読み込みの詳細については、「環境変数」ドキュメントを参照してください。
handleAuth()
をアプリに追加します。これにより、認証フローのさまざまな部分を実行する次のルート ハンドラーが内部で作成されます。
/api/auth/login
: Next.js アプリケーションは、ユーザーがログインできるように ID プロバイダーにリダイレクトします (オプションでreturnTo
パラメーターを渡して、ログイン後にカスタムの相対 URL に戻ることができます (例/api/auth/login?returnTo=/profile
)。
/api/auth/callback
: ログインに成功すると、アイデンティティ プロバイダーはユーザーをこのルートにリダイレクトします。
/api/auth/logout
: Next.js アプリケーションはユーザーをログアウトします。
/api/auth/me
: ユーザープロファイル情報を JSON 形式で取得できます。
ルーターに応じてセットアップを続行します。
ページルーター
アプリルーター
/pages/api
ディレクトリの下に動的 API ルート ハンドラーを作成します。
/pages/api/
ディレクトリの下にauth
ディレクトリを作成します。
新しく作成したauth
ディレクトリの下に[auth0].js
ファイルを作成します。
動的 API ルート ファイルへのパスは/pages/api/auth/[auth0].js
になります。次のようにそのファイルにデータを入力します。
import { handleAuth } から '@auth0/nextjs-auth0'; デフォルトの handleAuth() をエクスポート;
pages/_app.js
コンポーネントをUserProvider
コンポーネントでラップします。
// pages/_app.jsimport React from 'react';import { UserProvider } from '@auth0/nextjs-auth0/client';export デフォルト関数 App({ Component, pageProps }) { return (<UserProvider> <Component {...pageProps} /></UserProvider> );}
useUser()
フックによって返されたuser
オブジェクトが定義されているかどうかを確認することで、ユーザーが認証されているかどうかを判断できるようになりました。ユーザーを適切な自動生成ルートにリダイレクトすることで、Next.js アプリケーションのフロントエンド層からユーザーをログインまたはログアウトすることもできます。
// pages/index.jsimport { useUser } from '@auth0/nextjs-auth0/client';デフォルト関数 Index() をエクスポート { const { ユーザー、エラー、isLoading } = useUser(); if (isLoading) は <div>Loading...</div> を返します。 if (エラー) <div>{error.message}</div> を返します。 if (user) {return ( <div>ようこそ {user.name}! <a href="/api/auth/logout">ログアウト</a> </div>); } return <a href="/api/auth/login">ログイン</a>;}
次の lint ルールでは、アンカー タグの代わりに
Link
コンポーネントの使用を推奨する場合があります。Link
コンポーネントは、ページ間のクライアント側の遷移を実行することを目的としています。リンクはページではなく API ルートを指しているため、リンクをアンカー タグとして保持する必要があります。
続行する前に、「React Server コンポーネントでのこの SDK の使用」を確認してください。
包括的な動的 API ルート ハンドラーを/app/api
ディレクトリの下に作成します (厳密に言えば、API ルートを/api
の下に置く必要はありませんが、簡単にするためにこの規則を維持します)。
/app/
ディレクトリの下にapi
ディレクトリを作成します。
新しく作成した/app/api/
ディレクトリの下にauth
ディレクトリを作成します。
新しく作成したauth
ディレクトリの下に[auth0]
ディレクトリを作成します。
新しく作成した[auth0]
ディレクトリの下にroute.js
ファイルを作成します。
動的 API ルート ファイルへのパスは/app/api/auth/[auth0]/route.js
になります。次のようにそのファイルにデータを入力します。
import { handleAuth } from '@auth0/nextjs-auth0';export const GET = handleAuth();
UserProvider
レイアウトに追加しますapp/layout.js
コンポーネントをUserProvider
コンポーネントでラップします。
// app/layout.jsimport React from 'react';import { UserProvider } from '@auth0/nextjs-auth0/client';export デフォルト関数 App({ Children }) { return (<UserProvider> <body>{children}</body></UserProvider> );}
useUser()
フックによって返されたuser
オブジェクトが定義されているかどうかを確認することで、ユーザーが認証されているかどうかを判断できるようになりました。ユーザーを適切な自動生成ルートにリダイレクトすることで、Next.js アプリケーションのフロントエンド層からユーザーをログインまたはログアウトすることもできます。
// pages/index.js'use client';import { useUser } from '@auth0/nextjs-auth0/client';export デフォルト関数 Index() { const { ユーザー、エラー、isLoading } = useUser(); if (isLoading) は <div>Loading...</div> を返します。 if (エラー) <div>{error.message}</div> を返します。 if (user) {return ( <div>ようこそ {user.name}! <a href="/api/auth/logout">ログアウト</a> </div>); } return <a href="/api/auth/login">ログイン</a>;}
次の lint ルールでは、アンカー タグの代わりに
Link
コンポーネントの使用を推奨する場合があります。Link
コンポーネントは、ページ間のクライアント側の遷移を実行することを目的としています。リンクはページではなく API ルートを指しているため、リンクをアンカー タグとして保持する必要があります。
App ディレクトリ内のサーバー コンポーネント (ページおよびレイアウトを含む) は Cookie に書き込むことができません。
セッションの読み取りと更新をサーバー コンポーネントのみに依存する場合は、次の点に注意する必要があります。
ローリング セッション (この SDK のデフォルト) がある場合、ユーザーがサイトにアクセスしても有効期限は更新されません。そのため、セッションは予想よりも早く期限切れになる可能性があります (これを軽減するためにwithMiddlewareAuthRequired
を使用できます)。
アクセス トークンを更新すると、新しいアクセス トークンはセッションに保持されません。したがって、その後アクセス トークンを取得しようとすると、常にセッション内の期限切れのアクセス トークンが更新されます。
セッションに他の更新を行った場合、それらはリクエスト間で保持されません。
Cookie は、ミドルウェア、ルート ハンドラー、サーバー アクションから書き込むことができます。
その他の包括的な例については、EXAMPLES.md ドキュメントを参照してください。
import * from @auth0/nextjs-auth0
import * from @auth0/nextjs-auth0/edge
構成オプションと環境変数
initAuth0
ハンドル認証
ハンドルログイン
ハンドルコールバック
ハンドルログアウト
ハンドルプロファイル
withApiAuth必須
withPageAuth必須
セッションの取得
更新セッション
アクセストークンの取得
withMiddlewareAuthRequired (Edge のみ)
import * from @auth0/nextjs-auth0/client
ユーザープロバイダー
使用ユーザー
withPageAuth必須
import * from @auth0/nextjs-auth0/testing
セッションクッキーを生成する
詳細については、自動生成された API ドキュメントをご覧ください。
すべての Cookie はHttpOnly, SameSite=Lax
に設定され、アプリケーションのAUTH0_BASE_URL
がhttps
の場合はSecure
に設定されます。
HttpOnly
設定により、クライアント側 JavaScript が Cookie にアクセスできないようになり、XSS 攻撃の攻撃対象領域が減少します。
SameSite=Lax
設定は、CSRF 攻撃の軽減に役立ちます。 SameSite について詳しくは、ブログ投稿「今後のブラウザーの動作変更: 開発者が知っておくべきこと」をご覧ください。
多くのホスティング プロバイダーは、ユーザーにできるだけ早くデータを提供するために、コンテンツをエッジでキャッシュすることを提案します。たとえば、応答に必要なキャッシュ ヘッダーを指定すると、Vercel はすべての静的コンテンツとサーバーレス関数について Vercel Edge Network 上のコンテンツをキャッシュします。
認証を必要とする応答をキャッシュすることは一般に悪い考えです。応答のコンテンツがキャッシュしても安全であるように見えても、応答内に安全ではない他のデータが含まれている可能性があります。
この SDK はデフォルトでローリング セッションを提供します。つまり、セッションを読み取る応答には、Cookie の有効期限を更新するためのSet-Cookie
ヘッダーが含まれます。 Vercel および他のホスティング プロバイダーには、キャッシュされた応答にSet-Cookie
ヘッダーが含まれるため、応答のコンテンツをパブリックにキャッシュできると思われる場合でも、応答のSet-Cookie
ヘッダーはキャッシュできません。
ホスティング プロバイダーのキャッシュ ルールを確認してください。ただし、一般に、認証を必要とする応答や、認証を確認するためにセッションにアクセスする応答を決してキャッシュすべきではありません(例: withApiAuthRequired
、 withPageAuthRequired
、またはgetSession
またはgetAccessToken
のみを使用する場合)。
redirect_uri
コールバックの Auth0 から発生するエラーには、OpenID Connect error
およびerror_description
クエリ パラメーターを介して反映されたユーザー入力が含まれている場合があります。このため、 IdentityProviderError
のmessage
、 error
、およびerror_description
プロパティに対していくつかの基本的なエスケープを実行します。
ただし、独自のエラー ハンドラーを作成する場合は、最初に他の HTML コンテキスト用に適切にエスケープするテンプレート エンジンを使用せずに、エラーmessage
、またはerror
とerror_description
プロパティをレンダリングしないでください。
Next.js を使用すると、ベース パスを使用してドメインのサブパスに Next.js アプリケーションをデプロイし、国際化ルーティングを使用して国際化 (i18n) ルートを提供できます。
これらの機能を使用すると、アプリケーションの URL が変更されるため、nextjs-auth0 ルートへの URL も変更されます。これに対応するために、SDK 内のさまざまな場所で URL をカスタマイズできます。
たとえば、 basePath: '/foo'
の場合、これをAuth0Provider
で指定されたloginUrl
とprofileUrl
の先頭に追加する必要があります。
// _app.jsxfunction App({ Component, pageProps }) { return (<UserProvider loginUrl="/foo/api/auth/login" profileUrl="/foo/api/auth/me"> <Component {...pageProps} /></UserProvider> );}
また、ログインまたはログアウトへのリンクには、 basePath
を含める必要があります。
<a href="/foo/api/auth/login">ログイン</a><br /><a href="/foo/api/auth/logout">ログアウト</a>
BaseUrl (またはAUTH0_BASE_URL
環境変数) を構成する必要があります。例えば:
# .env.localAUTH0_BASE_URL=http://localhost:3000/foo
サーバー側の withPageAuthRequired で保護されているページについては、必要に応じて、 basePath
とlocale
に応じてreturnTo
パラメーターを更新する必要があります。
// ./pages/my-ssr-page.jsxexport デフォルト MySsrPage = () => <></>;const getFullReturnTo = (ctx) => { // TODO: ctx.resolvedUrl、ctx.locale に基づいて getFullReturnTo を実装します。 // および next.config.js の BasePath と i18n 設定。 return '/foo/en-US/my-ssr-page';};export const getServerSideProps = (ctx) => { const returnTo = getFullReturnTo(ctx.req); return withPageAuthRequired({ returnTo })(ctx);};
Next.js アプリケーションに適した Auth0 React SDK、auth0-react も提供しています。
auth0-react
で使用される SPA セキュリティ モデルは、この SDK で使用される Web アプリケーション セキュリティ モデルとは異なります。つまり、この SDK は Cookie セッションを使用してページと API ルートを保護します (「Cookie とセキュリティ」を参照)。 auth0-react
のような SPA ライブラリは、ユーザーの ID トークンとアクセス トークンをブラウザーに直接保存し、それらを使用して外部 API に直接アクセスします。
両方のモデルのセキュリティへの影響を認識する必要があります。ただし、次のシナリオのいずれかを満たす場合は、auth0-react の方がニーズに適している可能性があります。
Next.js で静的 HTML エクスポートを使用しています。
サーバー側のレンダリング中にユーザー データにアクセスする必要はありません。
Next.js API ルートをプロキシとして使用して外部 API を呼び出すのではなく、アクセス トークンを取得してフロントエンド レイヤーから直接外部 API を呼び出したいと考えています。
デフォルトでは、SDK はアプリケーションの存続期間中実行されるシングルトン インスタンスを作成および管理します。アプリケーションをテストするときは、テスト間で状態が漏洩しないように、このインスタンスをリセットする必要がある場合があります。
Jest を使用している場合は、各テストの後にjest.resetModules()
を使用することをお勧めします。あるいは、SDK の独自のインスタンスを作成して、テストの合間に再作成できるようにすることもできます。
エンドツーエンドのテストについては、モック OIDC プロバイダーの使用方法をご覧ください。
デプロイについては、サンプル アプリを Vercel にデプロイする方法をご覧ください。
このリポジトリへのフィードバックと貢献に感謝いたします。始める前に、以下をお読みください。
Auth0 の一般的な貢献ガイドライン
Auth0 の行動規範ガイドライン
このリポジトリの貢献ガイド
公開されている GitHub 問題トラッカーでセキュリティの脆弱性を報告しないでください。責任ある開示プログラムには、セキュリティ問題を開示する手順が詳しく記載されています。
Auth0 は、実装が簡単で適応性のある認証および認可プラットフォームです。詳細については、「Why Auth0?」をご覧ください。
このプロジェクトは MIT ライセンスに基づいてライセンスされています。詳細については、LICENSE ファイルを参照してください。