0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

AmplifyとCognitoでの認証をどこまでもシンプルに

Last updated at Posted at 2025-12-11

はじめに

AmplifyとCognitoを使ってフロントエンド環境と認証環境簡単にできる・・・・というのが弊社内では実践されていました。
しかし、いざ自分でやってみるとどういうフローなのかが把握できず、結局構築した知識のある他メンバーに頼るところもありました。
そこで、今回自分が主担当になる案件があるので、そこにAmplifyを導入すべく、自分ながらに整理してみようと思った次第です。

このブログの目的

どこまでも質素にすることにより、AmplifyとCognitoを用いた認証を動かすために何が必要なのかを理解するため。(そのため、今回はCSSをほぼなくし、骨同然のコードで行きます。)

前提

  • AWSのキーがなく、CLIを使わない人
  • GitHubを使っていること
  • 追加のCSSコーディングはご自分で、ご自由に

AmplifyとCognitoとはなにか

AmplifyとCognitoは、AWSが提供する認証・バックエンドサービスです。

  • Amplify: フロントエンドアプリケーションの開発・デプロイを支援するサービス。認証UIコンポーネントも提供しています。
  • Cognito: ユーザー認証・認可を管理するサービス。ユーザープールを作成することで、ユーザー登録・ログイン機能を簡単に実装できます。

ファイル構成

このプロジェクトのファイル構成は以下の通りです。

amplify-cognito-qiita/
├── src/
│   ├── app/
│   │   ├── ClientLayout.tsx      # Authenticator.Providerでラップするクライアントコンポーネント
│   │   ├── layout.tsx             # ルートレイアウト
│   │   ├── page.tsx               # ホームページ(認証状態に応じてリダイレクト)
│   │   ├── login/
│   │   │   └── page.tsx           # ログインページ
│   │   └── dashboard/
│   │       └── page.tsx           # ダッシュボードページ(認証必須)
│   └── lib/
│       └── amplify.ts             # Amplifyの設定ファイル(重要!)
├── amplify/                       # npm create amplify@latest で自動生成
├── package.json                   # プロジェクトルート
├── tsconfig.json                  # プロジェクトルート(TypeScript設定)
└── next.config.ts                 # プロジェクトルート(Next.js設定)

amplify/フォルダはnpm create amplify@latestコマンドで自動生成されます。

各ファイルの役割

amplify/フォルダ(自動生成)

npm create amplify@latestコマンドで自動生成されます。手動で作成する必要はありません。

生成されるファイル:

  • amplify/backend.ts - バックエンド定義(認証・データなどのリソース統合)
  • amplify/auth/resource.ts - Cognito認証設定
  • amplify/data/resource.ts - データベース設定
  • amplify/package.json - Amplify設定用
  • amplify/tsconfig.json - TypeScript設定

Amplify Hostingにデプロイすると、この定義に基づいてCognito User Poolなどが自動的に作成されます。

src/lib/amplify.ts

Amplifyの設定を行うファイルです。Gen 2のamplify_outputs.jsonから設定を読み込んで、Amplify.configure()を実行します。amplify_outputs.jsonが存在しない場合は、環境変数から設定を読み込みます。

import { Amplify } from 'aws-amplify';

// Gen 2のamplify_outputs.jsonから設定を読み込む
// このファイルは `npx ampx sandbox` を実行すると自動生成されます
// または、Amplify Hostingにデプロイした後、生成されたamplify_outputs.jsonをローカルにコピーすることも可能

let amplifyConfig: any;

try {
  // amplify_outputs.jsonが存在する場合(sandbox起動後、または本番環境からコピーした場合)
  const outputs = require('../../amplify_outputs.json');
  amplifyConfig = outputs;
} catch {
  // フォールバック: 環境変数から設定を読み込む(sandboxが使えない場合)
  // AWSコンソールからCognito User Poolの情報を取得して、.env.localに設定してください
  const userPoolId = process.env.NEXT_PUBLIC_USER_POOL_ID;
  const userPoolClientId = process.env.NEXT_PUBLIC_USER_POOL_CLIENT_ID;
  const region = process.env.NEXT_PUBLIC_REGION || 'ap-northeast-1';

  if (userPoolId && userPoolClientId) {
    amplifyConfig = {
      Auth: {
        Cognito: {
          userPoolId,
          userPoolClientId,
          region,
        }
      }
    };
  } else {
    console.warn(
      '⚠️ Amplify設定が見つかりません。\n' +
      '以下のいずれかの方法で設定してください:\n' +
      '1. 開発環境: `npx ampx sandbox` を実行してamplify_outputs.jsonを生成\n' +
      '2. 本番環境から: Amplify Hostingにデプロイ後、生成されたamplify_outputs.jsonをローカルにコピー\n' +
      '3. 手動設定: AWSコンソールからCognito情報を取得し、.env.localに設定(NEXT_PUBLIC_USER_POOL_ID, NEXT_PUBLIC_USER_POOL_CLIENT_ID, NEXT_PUBLIC_REGION)'
    );
    amplifyConfig = {};
  }
}

Amplify.configure(amplifyConfig);

export default amplifyConfig;

重要なポイント:

  • Gen 2ではamplify_outputs.jsonから設定を自動的に読み込みます(優先)
  • amplify_outputs.jsonが存在しない(または空の)場合、環境変数から設定を読み込みます(フォールバック)
  • 本番環境(Amplify Hosting): デプロイ時に自動的にamplify_outputs.jsonが生成・適用されます
  • ローカル開発: 本番デプロイ後、Cognitoの情報を環境変数に設定することで動作します(詳細は後述)

src/app/ClientLayout.tsx

アプリ全体をAuthenticator.Providerでラップするクライアントコンポーネントです。これにより、アプリ全体で認証状態を管理できます。

'use client';

import '@/lib/amplify';  // ← amplify.tsをインポートして設定を読み込む
import '@aws-amplify/ui-react/styles.css';  // ← Amplify UIのスタイル
import { Authenticator } from '@aws-amplify/ui-react';

export default function ClientLayout({ children }: { children: React.ReactNode }) {
  return (
    <Authenticator.Provider>
      {children}
    </Authenticator.Provider>
  );
}

パスエイリアス(@/*)について:

  • import '@/lib/amplify'@src/ ディレクトリを指すパスエイリアスです
  • このエイリアスは tsconfig.json で設定されています(後述)
  • もし @ でエラーが出る場合は、tsconfig.jsonpaths 設定を確認してください
  • 代替案として、相対パス import '../../lib/amplify' も使用できますが、エイリアスの方が一般的です

src/app/layout.tsx

Next.jsのルートレイアウトです。ClientLayoutを使用しています。

import ClientLayout from "./ClientLayout";

export default function RootLayout({
  children,
}: Readonly<{
  children: React.ReactNode;
}>) {
  return (
    <html lang="ja">
      <body>
        <ClientLayout>
          {children}
        </ClientLayout>
      </body>
    </html>
  );
}

src/app/page.tsx

ホームページです。認証状態に応じて/dashboardまたは/loginにリダイレクトします。

'use client';

import { useAuthenticator } from '@aws-amplify/ui-react';
import { useEffect } from 'react';

export default function Home() {
  const { authStatus } = useAuthenticator();

  useEffect(() => {
    if (authStatus === 'authenticated') {
      window.location.href = '/dashboard';
    } else if (authStatus === 'unauthenticated') {
      window.location.href = '/login';
    }
  }, [authStatus]);

  return <div>読み込み中...</div>;
}

src/app/login/page.tsx

ログインページです。Authenticatorコンポーネントを使用してログインUIを表示します。

'use client';

import { Authenticator, useAuthenticator } from '@aws-amplify/ui-react';
import { useEffect } from 'react';

export default function LoginPage() {
  const { authStatus } = useAuthenticator();

  useEffect(() => {
    if (authStatus === 'authenticated') {
      window.location.href = '/dashboard';
    }
  }, [authStatus]);

  if (authStatus === 'authenticated') {
    return <div>ダッシュボードに移動中...</div>;
  }

  return (
    <div>
      <h2>ログイン</h2>
      <Authenticator />  {/* ← Amplifyが提供するログインUI */}
    </div>
  );
}

src/app/dashboard/page.tsx

ダッシュボードページです。認証されていない場合はログインページにリダイレクトします。

'use client';

import { useAuthenticator } from '@aws-amplify/ui-react';
import { useEffect } from 'react';

export default function DashboardPage() {
  const { user, signOut, authStatus } = useAuthenticator();

  useEffect(() => {
    if (authStatus === 'unauthenticated') {
      window.location.href = '/login';
    }
  }, [authStatus]);

  if (authStatus === 'unauthenticated') {
    return <div>ログインページに移動中...</div>;
  }

  if (authStatus !== 'authenticated') {
    return <div>読み込み中...</div>;
  }

  return (
    <div>
      <p>ユーザー名: {user?.username || 'Unknown'}</p>
      <p>メール: {user?.signInDetails?.loginId || 'Unknown'}</p>
      <button onClick={() => signOut()}>ログアウト</button>
    </div>
  );
}

tsconfig.json(プロジェクトルート)

TypeScriptの設定ファイルです。パスエイリアスの設定が重要です。

{
  "compilerOptions": {
    "target": "ES2017",
    "lib": ["dom", "dom.iterable", "esnext"],
    "allowJs": true,
    "skipLibCheck": true,
    "strict": true,
    "noEmit": true,
    "esModuleInterop": true,
    "module": "esnext",
    "moduleResolution": "bundler",
    "resolveJsonModule": true,
    "isolatedModules": true,
    "jsx": "preserve",
    "incremental": true,
    "plugins": [
      {
        "name": "next"
      }
    ],
    "paths": {
      "@/*": ["./src/*"]
    }
  },
  "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"],
  "exclude": ["node_modules"]
}

重要なポイント:

  • pathsセクションに"@/*": ["./src/*"]が設定されている必要があります
  • この設定により、import '@/lib/amplify'のように@を使ってsrc/ディレクトリからの相対パスでインポートできます

package.json(プロジェクトルート)

プロジェクトの依存関係とスクリプトを定義するファイルです。

{
  "name": "amplify-cognito-qiita",
  "version": "0.1.0",
  "private": true,
  "scripts": {
    "dev": "next dev",
    "build": "next build",
    "start": "next start",
    "lint": "eslint"
  },
  "dependencies": {
    "@aws-amplify/core": "^6.14.0",
    "@aws-amplify/ui-react": "^6.12.0",
    "aws-amplify": "^6.15.8",
    "next": "15.5.3",
    "react": "18.3.1",
    "react-dom": "18.3.1"
  },
  "devDependencies": {
    "@aws-amplify/backend": "^1.18.0",
    "@aws-amplify/backend-cli": "^1.8.0",
    "@eslint/eslintrc": "^3",
    "@tailwindcss/postcss": "^4",
    "@types/node": "^20",
    "@types/react": "^18",
    "@types/react-dom": "^18",
    "aws-cdk-lib": "^2.216.0",
    "constructs": "^10.4.3",
    "esbuild": "^0.27.1",
    "eslint": "^9",
    "eslint-config-next": "15.5.3",
    "tailwindcss": "^4",
    "tsx": "^4.21.0",
    "typescript": "^5.9.3"
  }
}

重要なポイント:

  • aws-amplify@aws-amplify/ui-reactdependenciesに含まれている必要があります
  • @aws-amplify/backend@aws-amplify/backend-clidevDependenciesに含まれている必要があります

next.config.ts(プロジェクトルート)

Next.jsの設定ファイルです。

import type { NextConfig } from "next";

const nextConfig: NextConfig = {
  /* config options here */
};

export default nextConfig;

今回は基本的な設定のみで動作します。

実装の流れ

この記事の流れ:

  1. ファイルを作成する
  2. パッケージをインストール & Amplifyを初期化する
  3. GitHubにプッシュする
  4. Amplify Hostingでデプロイ → Cognitoも自動設定される!
  5. 本番環境で動作確認
  6. (補足)ローカルでも動かせるようにする

AWS CLIの設定は一切不要です。Amplify Hostingが全て自動で処理してくれます。


1. ファイルを作成する

まず、プロジェクトに必要なファイルを作成します。

1-1. プロジェクトディレクトリを作成

mkdir amplify-cognito-qiita
cd amplify-cognito-qiita

1-2. 各ファイルを作成

上記の「各ファイルの役割」セクションで説明したファイルを順次作成していきます。

作成するファイル一覧:

  • src/lib/amplify.ts
  • src/app/ClientLayout.tsx
  • src/app/layout.tsx
  • src/app/page.tsx
  • src/app/login/page.tsx
  • src/app/dashboard/page.tsx
  • package.json
  • tsconfig.json
  • next.config.ts

amplify/フォルダは次のステップで自動生成されます。


2. パッケージをインストール & Amplifyを初期化する

2-1. パッケージをインストール

package.jsonを作成したら、依存関係をインストールします:

npm install

これで、Next.js、React、Amplify関連のパッケージがインストールされます。
なお、package-lock.jsonもコミットしましょう。

2-2. Amplifyを初期化する

以下のコマンドを実行して、amplify/フォルダを自動生成します:

npm create amplify@latest
✔ Where should we create your project? .

と出たらそのままEnterを押しましょう。

このコマンドを実行すると、amplify/フォルダが作成され、以下のファイルが自動生成されます:

  • amplify/backend.ts - バックエンド定義
  • amplify/auth/resource.ts - Cognito認証設定(メールログイン有効)
  • amplify/data/resource.ts - データベース設定
  • amplify/package.json
  • amplify/tsconfig.json

これでAmplifyの設定は完了です! 手動でamplifyフォルダを作成する必要はありません。


3. GitHubにプッシュする

ファイルを作成したら、GitHubにプッシュします。

3-1. Gitリポジトリを初期化

git init .

3-2. .gitignoreを作成

amplify_outputs.jsonはAmplify Hostingが自動生成するファイルなので、Gitにコミットしないようにします。

echo "node_modules/" >> .gitignore
echo "amplify_outputs.json" >> .gitignore
echo ".env.local" >> .gitignore
echo ".next/" >> .gitignore

3-3. コミットしてプッシュ

git add .
git commit -m "Amplify認証の初期実装"
git branch -M main
git remote add origin あなたのレポジトリ.git
git push -u origin main

4. Amplify Hostingでデプロイする

ここが一番のポイントです。Amplify Hostingにデプロイするだけで、Cognitoも自動的に設定されます

4-1. AWS Amplifyコンソールに移動

  1. AWSコンソールにログイン
  2. 「Amplify」サービスを検索して移動
  3. 「新しいアプリを作成」をクリック

4-2. GitHubリポジトリを接続

  1. バージョン管理ツールで「GitHub」を選択
  2. GitHubとの連携を許可
  3. 作成したリポジトリを選択

スクリーンショット 2025-11-05 18.33.51.png

一覧にリポジトリが表示されない場合は、「GitHubのアクセス許可をアップデート」をクリックして、リポジトリへのアクセスを許可してください。

スクリーンショット 2025-11-05 18.30.26.png

4-3. ブランチを選択してデプロイ

  1. ブランチ(通常はmain)を選択
  2. 「次へ」をクリック
  3. 設定を確認して「保存してデプロイ」をクリック

4-4. デプロイ完了を待つ

デプロイが開始されます。おおよそ3〜5分で完了します。

この間に何が起こっているか:

  • Next.jsアプリケーションがビルドされる
  • amplify/backend.tsの定義に基づいてCognito User Poolが自動作成される
  • amplify_outputs.jsonが自動生成され、フロントエンドに適用される
  • アプリケーションがホスティングされる

AWS CLIの設定は一切不要です! Amplify Hostingが全て自動で処理してくれます。


5. 動作確認 - できた!パチパチ!

デプロイが成功したら、Amplifyが提供するURLにアクセスして動作確認を行います。

確認項目

  1. ホームページ(/: 認証状態に応じて /dashboard または /login にリダイレクトされる

  2. ログインページ(/login: AmplifyのログインUIが表示される

    • 新規ユーザー登録ができる
    • 既存ユーザーでログインができる

スクリーンショット 2025-11-05 19.03.37.png

あらかじめUIが準備されているのがすごいところです。

  1. ダッシュボード(/dashboard: ログイン後、ユーザー情報が表示される
    • ユーザー名が表示される
    • メールアドレスが表示される
    • ログアウトボタンが動作する

スクリーンショット 2025-11-05 19.04.22.png

ユーザ名はCognitoのほうのユーザー管理画面にも表示されているものです。

スクリーンショット 2025-11-05 17.50.49.png

🎉 おめでとうございます!これで本番環境での認証機能が動作しています!


6. (補足)ローカルでも動かせるようにする

本番環境が動いたら、ローカル開発環境でも動作させたい場合があります。

Amplify Hostingでデプロイすると、Cognito User Poolが自動的に作成されています。このCognitoの情報をローカルの環境変数に設定することで、ローカルでも同じ認証機能を使えるようになります。

6-1. CognitoのIDを確認する

  1. AWSコンソールにログイン
  2. 「Cognito」サービスに移動
  3. 作成されたUser Poolを選択(Amplifyが自動作成したもの)
  4. 以下の情報をメモします:
    • User Pool ID(例: ap-northeast-1_xxxxxxxxx
    • App Client ID(「アプリの統合」タブ →「アプリクライアント」から取得)

6-2. 環境変数を設定

プロジェクトルートに.env.localファイルを作成し、以下の環境変数を設定します:

NEXT_PUBLIC_USER_POOL_ID=ap-northeast-1_xxxxxxxxx
NEXT_PUBLIC_USER_POOL_CLIENT_ID=xxxxxxxxxxxxxxxxxxxxxxxxxx
NEXT_PUBLIC_REGION=ap-northeast-1

注意: .env.local.gitignoreに追加して、Gitにコミットしないようにしてください。

6-3. ローカルで動作確認

npm run dev

ブラウザで http://localhost:3000 にアクセスすると、本番環境と同じ認証機能が動作します。

ポイント: src/lib/amplify.tsにはフォールバック処理が実装されているため、amplify_outputs.jsonが存在しない場合は自動的に環境変数から設定を読み込みます。


(参考)sandboxを使う方法

AWS CLIが使える環境であれば、npx ampx sandboxコマンドでローカル専用のCognito環境を作成することもできます。

npx ampx sandbox

このコマンドを実行すると:

  • ローカル開発専用のCognito User Poolが作成されます
  • amplify_outputs.jsonが自動生成されます

ただし、この方法にはAWS認証情報(AWS CLIの設定または環境変数)が必要です。 CLIを使わない方は、上記の環境変数を使った方法をおすすめします。

まとめ

この記事で紹介した流れ:

  1. ファイルを作成 → コードをコピペするだけ
  2. npm install & npm create amplify@latest → amplifyフォルダが自動生成
  3. GitHubにプッシュ → いつもの開発フロー
  4. Amplify Hostingでデプロイ → Cognitoも自動設定!
  5. 本番環境で動作確認 → 成功!
  6. (必要に応じて)ローカル開発 → 環境変数でCognito情報を設定

AWS CLIは一切不要です。Amplify Hostingが全て自動で処理してくれます。


技術的なポイント:

  1. npm create amplify@latestamplify/フォルダを自動生成 → 認証設定が自動で作られる
  2. Amplify Hostingにデプロイ → Cognito User Poolが自動作成される
  3. Amplify.configure() を実行 → 本番ではamplify_outputs.jsonから自動読み込み
  4. Authenticator.Provider でアプリ全体をラップ → 認証状態をアプリ全体で管理

ローカル開発について:

  • 本番デプロイ後、CognitoのIDを環境変数(.env.local)に設定すればローカルでも動作します
  • AWS CLIが使える方はnpx ampx sandboxも利用可能です(参考セクション参照)

最後に ~AI時代になぜこのブログを書こうと思ったか~

上記の内容は、もしかすると「今やCursorとかAIがあるんだからわざわざ読むことなくない?」と思うかもしれません。ブログを書く意味を問われていると思います。
確かに、今回のこのブログも、ソースコードはほぼCursorに任せましたし、なんなら上記の記事の基本的な部分はほとんどCursorです。では、なぜか。

結局AIも間違えるからです。
それによってラリーが数回続きます。

そこで、間違いのないように人間が整えて、できるだけ早く理解できるコンテンツとして提供することに、コンテンツそのものにも、そして執筆者の私にも価値が生まれるのかもしれないと思い、今回の執筆とします。

コメントありましたらお気軽にどうぞ!ありがとうございました!

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?