Next.jsからAmplifyカテゴリAPIを使用する
このガイドでは、Next.jsサーバーサイドランタイムからAmplify Auth、GraphQL API、REST API、およびStorageカテゴリAPIを使用する方法について説明します。
始める前に、以下が必要です:
Next.jsでAmplifyを設定
Next.jsアプリのサーバーサイドでAmplify APIを使用するには、runWithAmplifyServerContext関数を作成する必要があります。
コードベースのutilsフォルダの下にamplifyServerUtils.tsファイルを作成できます。このファイルで、Amplify CLIによって生成されるamplifyconfiguration.jsonファイルからAmplify設定オブジェクトをインポートし、createServerRunner関数を使用してrunWithAmplifyServerContext関数を作成します。
例えば、utils/amplifyServerUtils.tsファイルに以下のコンテンツが含まれる場合があります:
import { createServerRunner } from '@aws-amplify/adapter-nextjs';import config from '@/amplifyconfiguration.json';
export const { runWithAmplifyServerContext } = createServerRunner({ config});エクスポートされたrunWithAmplifyServerContext関数を使用して、分離されたリクエストコンテキストでAmplify APIを呼び出すことができます。使用例はここを参照してください。
Next.jsアプリのクライアント側でAmplifyライブラリを使用する場合、シングルページアプリケーションでAmplifyを使用する場合と同じようにAmplify.configureを呼び出すことでAmplifyを設定する必要があります。
'use client';
import config from '@/amplifyconfiguration.json';import { Amplify } from 'aws-amplify';
Amplify.configure(config, { ssr: true // Next.jsでAmplifyを使用する場合は必須});
export default function RootLayoutThatConfiguresAmplifyOnTheClient({ children}: { children: React.ReactNode;}) { return children;}詳細を確認Next.js App RouterアプリケーションでのAmplifyの設定
Next.js App Routerを使用している場合、Amplifyを設定するクライアントコンポーネントを作成し、ルートレイアウトにインポートできます。
ConfigureAmplifyClientSide.tsx:
'use client';
import { Amplify } from 'aws-amplify';import config from '../amplifyconfiguration.json';
Amplify.configure(config, { ssr: true });
export default function ConfigureAmplifyClientSide() { return null;}layout.tsx:
import ConfigureAmplifyClientSide from '@/components/ConfigureAmplifyClientSide';import './globals.css';
import type { Metadata } from 'next';
export const metadata: Metadata = { title: 'Create Next App', description: 'Generated by create next app',};
export default function RootLayout({ children,}: { children: React.ReactNode;}) { return ( <html lang="en"> <body className="container pb-6"> <> <ConfigureAmplifyClientSide /> {children} </> </body> </html> );}Next.jsサーバーサイドランタイムでの認証
(実験的) サーバーサイドで認証を実行しHttpOnlyクッキーを有効にする
Next.jsアプリでサーバーサイド認証フローを有効にするには、追加の設定が必要です。
ステップ1 - 環境変数でアプリのオリジンを指定
Next.jsアプリに以下の環境変数を追加します。例えば、.envファイル内:
AMPLIFY_APP_ORIGIN=https://myapp.comこの環境変数がNext.jsアプリのサーバーランタイムでアクセスできることを確認してください。
ステップ2 - createAuthRouteHandlers関数をエクスポート
createAuthRouteHandlers関数は、サーバーサイド使用のためにAmplifyを設定するときにcreateServerRunner関数呼び出しによって作成されます。この関数をamplifyServerUtils.tsファイルからエクスポートできます。また、runtimeOptionsパラメータでクッキー属性を設定することもできます。
import { createServerRunner } from '@aws-amplify/adapter-nextjs';import config from '@/amplifyconfiguration.json';
export const { runWithAmplifyServerContext, createAuthRouteHandlers,} = createServerRunner({ config, runtimeOptions: { cookies: { domain: '.myapp.com', // すべてのサブドメインでクッキーを利用可能にする sameSite: 'strict', maxAge: 60 * 60 * 24 * 7 // 7日 } }});ステップ3 - Auth APIルートを設定
createAuthRouteHandlers関数を使用してAPIルートを作成します。例えば:
import { createAuthRouteHandlers } from "@/utils/amplifyServerUtils";
export const GET = createAuthRouteHandlers({ redirectOnSignInComplete: "/home", redirectOnSignOutComplete: "/sign-in",});import { createAuthRouteHandlers } from "@/utils/amplifyServerUtils";
export default createAuthRouteHandlers({ redirectOnSignInComplete: "/home", redirectOnSignOutComplete: "/sign-in",});上記の例では、Amplifyは以下のAPIルートを生成します:
| APIルート | 機能 |
|---|---|
/api/auth/sign-up | エンドユーザーがこのルートに移動すると、Amazon Cognito Managed Loginサインアップフォームにリダイレクトされます。サインアップとサインイン後、ルート/api/auth/sign-in-callbackにリダイレクトされます。 |
/api/auth/sign-in | エンドユーザーがこのルートに移動すると、Amazon Cognito Managed Loginサインインフォームにリダイレクトされます。サインイン後、ルート/api/auth/sign-in-callbackにリダイレクトされます。 |
/api/auth/sign-in?provider=<social-provider-name> | エンドユーザーがこのルートに移動すると、最初にAmazon Cognito Managed Loginにリダイレクトされ、次に指定されたソーシャルプロバイダーのサインインページにリダイレクトされます。サインイン後、ルート/api/auth/sign-in-callbackにリダイレクトされます。 |
/api/auth/sign-out | エンドユーザーがこのルートに移動すると、エンドユーザーはサインアウトし、ルート/api/auth/sign-out-callbackにリダイレクトされます。 |
/api/auth/sign-in-callback | Amazon Cognito Managed Loginはサインイン後、エンドユーザーをこのルートにリダイレクトします。Amplifyは認証トークンを交換してHttpOnlyクッキーとしてブラウザクッキーストアに保存し、エンドユーザーをredirectOnSignInCompleteパラメータで指定されたルートにリダイレクトします。 |
/api/auth/sign-out-callback | Amazon Cognito Managed Loginはサインアウト後、エンドユーザーをこのルートにリダイレクトします。Amplifyはアクセストークンとリフレッシュトークンを取り消し、ブラウザクッキーストアからトークンクッキーを削除し、エンドユーザーをredirectOnSignOutCompleteパラメータで指定されたルートにリダイレクトします。 |
Amazon Cognito Managed Loginページの言語をカスタマイズするには、/api/auth/sign-inおよび/api/auth/sign-upルートにlangクエリパラメータを追加できます。例えば、/api/auth/sign-in?lang=fr。サポートされている言語の詳細については、Managed loginローカライゼーションドキュメントを参照してください。
ステップ4 - リダイレクトURLをAmplifyのAuth Resourceに提供
amplify add authまたはamplify update authを実行してコールバックAPIルートをリダイレクトURLとして提供できます。詳細については、Auth カテゴリの設定を参照してください。上記の例を使用して、以下のリダイレクトURLを提供できます:
// サインインリダイレクトURI:https://myapp.com/api/auth/sign-in-callback
// サインアウトリダイレクトURI:https://myapp.com/api/auth/sign-out-callbackこれにより、Amazon Cognito Hosted UIがサーバーサイド認証フローをサポートできるようになります。最新のAmazon Cognito Managed Loginブランディングにアップグレードして、サインインおよびサインアップページをカスタマイズできます。詳細については、Amazon Cognitoユーザープールマネージドログインを参照してください。
ステップ5 - サーバーサイド認証フローを開始するためのアンカーリンクを使用
HTMLアンカーリンクを使用して、ユーザーをサインインおよびサインアップルートに移動させます。例えば:
export default function SignInButton() { return ( <a href="/api/auth/sign-in"> Sign In </a> );}export default function SignInWithGoogleButton() { return ( <a href="/api/auth/sign-in?provider=Google"> Sign In with Google </a> );}export default function SignUpButton() { return ( <a href="/api/auth/sign-up"> Sign Up </a> );}export default function SignOutButton() { return ( <a href="/api/auth/sign-out"> Sign Out </a> );}エンドユーザーが上記のボタンをクリックすると、対応するサーバーサイド認証フローが開始されます。
Next.js Middlewareを使用してユーザーセッションを検証
Next.jsアプリのミドルウェアでfetchAuthSession APIを使用して、ルートを保護するために入力リクエストに添付された認証セッションを確認できます。例えば:
import { fetchAuthSession } from 'aws-amplify/auth/server';import { NextRequest, NextResponse } from 'next/server';import { runWithAmplifyServerContext } from '@/utils/amplifyServerUtils';
export async function middleware(request: NextRequest) { const response = NextResponse.next();
const authenticated = await runWithAmplifyServerContext({ nextServerContext: { request, response }, operation: async (contextSpec) => { try { const session = await fetchAuthSession(contextSpec); return ( session.tokens?.accessToken !== undefined && session.tokens?.idToken !== undefined ); } catch (error) { console.log(error); return false; } } });
if (authenticated) { return response; }
return NextResponse.redirect(new URL('/sign-in', request.url));}
export const config = { matcher: [ /* * 以下で始まるリクエストパスを除くすべてのリクエストパスに一致: * - api (APIルート) * - _next/static (静的ファイル) * - _next/image (画像最適化ファイル) * - favicon.ico (faviconファイル) */ '/((?!api|_next/static|_next/image|favicon.ico|sign-in).*)' ]};この例では、入力リクエストが有効なユーザーセッションに関連付けられていない場合、リクエストは/sign-inルートにリダイレクトされます。
サーバーサイド使用のためのサポートされているAmplify API
サーバーで使用をサポートするすべてのAPIは、aws-amplify/<category>/serverサブパスからエクスポートされます。サーバーサイドユースケースには、これらのAPIを使用する必要があります。
| カテゴリ | API | サーバー (Node.js) Amplify ホスティング/Vercel | Vercel Edge Runtime (ミドルウェア) |
|---|---|---|---|
| Auth | fetchAuthSession | ✅ | ✅ |
| Auth | fetchUserAttributes | ✅ | ✅ |
| Auth | getCurrentUser | ✅ | ✅ |
| API (GraphQL) | generateServerClientUsingCookies | ✅ | |
| API (GraphQL) | generateServerClientUsingReqRes | ✅ | |
| API (REST) | GET | ✅ | |
| API (REST) | POST | ✅ | |
| API (REST) | PUT | ✅ | |
| API (REST) | DEL | ✅ | |
| API (REST) | HEAD | ✅ | |
| API (REST) | PATCH | ✅ | |
| Storage | getUrl | ✅ | |
| Storage | getProperties | ✅ | |
| Storage | list | ✅ | |
| Storage | remove | ✅ | |
| Storage | copy | ✅ |
Amplify JavaScript v5からの移行
Amplify JS v5のwithSSRContextユーティリティはAmplify JS v6では利用できなくなりました。@aws-amplify/adapter-nextjsからエクスポートされたcreateServerRunner関数を使用してrunWithAmplifyServerContext関数を作成し、この関数を使用してNext.jsアプリのサーバーサイドでAmplify API呼び出しを行う必要があります。使用例については、ここを参照してください。