Contents
AWS アカウント作成と Cognito ユーザープール・ID プールの基本設定
このセクションでは、AWS の無料利用枠を活用して Cognito の認証基盤を構築するまでの流れを解説します。まずは AWS アカウント取得から始め、ユーザープールと ID プールの作成・連携手順を具体的に示すので、初めてでもスムーズにセットアップできます。
AWS アカウント取得手順
AWS コンソールへのサインアップは数分で完了します。クレジットカード情報が必要ですが、無料利用枠の範囲内であれば課金は発生しません。
- 公式サイト( https://aws.amazon.com/ )へアクセスし 「Create an AWS Account」 をクリック
- メールアドレス・パスワードを入力し、画面の指示に従って個人情報とクレジットカード情報を登録
- 無料利用枠の確認画面で 「Activate」 を押すと、AWS マネジメントコンソールが使用可能になる
Cognito ユーザープール作成
ユーザープールは認証情報(メールアドレスやパスワード)を管理する中心的なリソースです。以下の設定は AWS が推奨するベストプラクティスに沿ったものです。
プール名・サインイン方法
|
1 2 3 |
プール名:プロジェクト名 + "UserPool"(例: myappUserPool) サインイン方式:メールアドレスまたは電話番号のいずれかを選択 |
パスワードポリシーと MFA
- 最低文字数:8 文字
- 必須文字種:英字(大文字・小文字)+数字+記号
- MFA:オプションで有効化可能(SMS または TOTP)
詳細な手順は AWS 公式ドキュメント「Amazon Cognito ユーザープールの作成」を参照してください。
Identity Pool(ID プール)の連携とロール設定
ID プールは 認可(IAM ロール)情報をユーザーに付与する役割を持ちます。以下の手順でユーザープールと ID プールを紐付け、必要なロールを自動生成します。
手順概要
- Cognito コンソールで 「Identity pools」 → 「Create identity pool」 を選択
- 「Enable access to unauthenticated identities(未認証ユーザーへのアクセス許可)」はオフ に設定
- 根拠:AWS のベストプラクティスでは、不要な匿名アクセスは攻撃対象を増やすリスクがあると明記されています(IAM ベストプラクティス – AWS Security Blog)。また、未認証ロールはデフォルトで広範な権限が付与されやすく、コスト増の要因にもなります。
- 先ほど作成したユーザープールを Authentication providers に紐付ける
- デフォルトで生成されるロールは以下の通り
Cognito_<AppName>Unauth_Role(未認証用)Cognito_<AppName>Auth_Role(認証済み用)
この設定により、認証済みユーザーは最小権限で AWS リソースへ安全にアクセスできます。
Amplify CLI/SDK のインストールと認証機能のセットアップ
Amplify は Cognito のリソース定義をコード化し、Infrastructure as Code(IaC) として管理できるツールです。ここでは CLI の導入から amplify add auth までの流れを詳しく見ていきます。
Amplify CLI のインストール
Node.js がインストール済みであれば、以下のどちらかの方法で CLI を取得できます。Yarn 2+(Berry)では yarn global add が非推奨 となるため、代替手段も併記します。
| 方法 | コマンド例 | 備考 |
|---|---|---|
| npm (最も汎用的) | npm install -g @aws-amplify/cli |
グローバルインストール |
| corepack + Yarn 3+ | corepack enable && yarn dlx @aws-amplify/cli |
Yarn のプラグイン方式で推奨 |
| pnpm | pnpm add -g @aws-amplify/cli |
高速インストールが可能 |
インストール後は以下を実行し、IAM 管理者ユーザーを作成して認証情報をローカルに保存します。
|
1 2 |
amplify configure |
プロジェクト初期化(amplify init)
React アプリのルートで次のコマンドを実行します。対話形式の質問にはプロジェクト名・環境名などを入力してください。
|
1 2 |
amplify init |
- 導入文:
amplify initは Amplify の作業領域(amplify/ディレクトリ)と、AWS 側の CloudFormation テンプレートを自動生成します。 - 主な設定項目
- プロジェクト名:例
react-cognito-sample(Git リポジトリ名と統一) - 環境名:
devを推奨、後でprod環境を追加可能 - エディタ・IDE:VS Code など好みのものを選択
実行後、amplify/ フォルダと src/aws-exports.js が生成されます。
認証リソースの追加(amplify add auth)
対話式質問に沿って手動設定で Cognito を構築します。以下は推奨設定例です。
|
1 2 |
amplify add auth |
| 質問 | 推奨回答 |
|---|---|
| Default configuration with Social Provider (OAuth) | No |
| Manual configuration | Yes |
| Authentication flow | USER_PASSWORD_AUTH |
| Multi‑factor authentication (MFA) | Optional |
| Password policy | 8 文字以上、英数字+記号必須 |
| Enable unauthenticated identities | No(前述の根拠参照) |
設定が完了したら以下でリソースをデプロイします。
|
1 2 |
amplify push --yes |
この操作により、CloudFormation が実行され Cognito ユーザープール・IDプールが作成されます。生成された aws-exports.js は次章で React アプリへインポートします。
React アプリへの Amplify UI v6 統合とカスタマイズ
Amplify UI v6 の <Authenticator> コンポーネントは、数行のコードだけでフル機能の認証画面を提供します。ここでは基本的な組み込み手順と、ブランドカラーに合わせたテーマカスタマイズ方法を示します。
aws-exports.js のインポートと Amplify 設定
src/main.jsx(または index.tsx)で SDK を初期化します。導入文として、これだけで Amplify が Cognito エンドポイントと自動的に連携することを説明します。
|
1 2 3 4 5 |
import { Amplify } from 'aws-amplify'; import awsExports from './aws-exports'; Amplify.configure(awsExports); |
<Authenticator> の基本使用例
App.jsx にラップすると、未認証時は自動的にサインイン画面が表示されます。導入文でコンポーネントの役割を簡潔に述べます。
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
import { Authenticator } from '@aws-amplify/ui-react'; function App() { return ( <Authenticator> {/* 認証済みユーザー向け UI */} {({ signOut, user }) => ( <div> <h1>Welcome, {user.username}!</h1> <button onClick={signOut}>Sign out</button> {/* ここにアプリ本体のルートコンポーネントを配置 */} </div> )} </Authenticator> ); } export default App; |
テーマ・スタイル カスタマイズ
ThemeProvider と defaultTheme を用いてブランドカラーを上書きできます。導入文で「テーマオブジェクトはトークンベースなので、細かい UI パーツまで一括変更できる」ことを強調します。
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
import { ThemeProvider, defaultTheme } from '@aws-amplify/ui-react'; const myTheme = { ...defaultTheme, name: 'my-theme', tokens: { colors: { brand: { primary: { value: '#1e88e5' }, // 主色 secondary: { value: '#ffb300' }, // 補助色 }, }, }, }; function Root() { return ( <ThemeProvider theme={myTheme}> <App /> </ThemeProvider> ); } export default Root; |
このようにテーマを上書きすれば、デザインガイドラインに完全に合致した認証 UI が実現します。
React Router v6 で認証ガードと API 呼び出しの実装
認可が必要なページは ProtectedRoute パターンで保護し、トークン取得・自動リフレッシュを統一的に扱うことで API 呼び出し時のヘッダー付与も簡単になります。
ProtectedRoute コンポーネントの作り方
src/components/ProtectedRoute.jsx に実装します。導入文で「このコンポーネントは認証状態を判定し、未認証の場合はトップページへリダイレクトする」ことを説明します。
|
1 2 3 4 5 6 7 8 9 10 11 |
import { Navigate, Outlet } from 'react-router-dom'; import { useAuthenticator } from '@aws-amplify/ui-react'; export default function ProtectedRoute() { const { authStatus } = useAuthenticator(context => [context.authStatus]); if (authStatus === 'loading') return null; // ローディング中は何も描画しない return authStatus === 'authenticated' ? <Outlet /> : <Navigate to="/" replace />; } |
ルーティング例
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
import { BrowserRouter, Routes, Route } from 'react-router-dom'; import ProtectedRoute from './components/ProtectedRoute'; import Dashboard from './pages/Dashboard'; import Home from './pages/Home'; function Router() { return ( <BrowserRouter> <Routes> <Route path="/" element={<Home />} /> {/* 認証が必要なルートは ProtectedRoute でラップ */} <Route element={<ProtectedRoute />}> <Route path="/dashboard" element={<Dashboard />} /> </Route> </Routes> </BrowserRouter> ); } export default Router; |
トークン取得と自動リフレッシュロジック
Amplify の Auth モジュールは内部でトークンの有効期限を監視し、必要に応じて自動的にリフレッシュします。以下は ID トークン を取得するユーティリティ関数です。
|
1 2 3 4 5 6 7 8 9 10 11 |
import { Auth } from 'aws-amplify'; /** * 現在の認証セッションから ID トークン(JWT)を取得。 * 有効期限が近い場合は Amplify が自動的にリフレッシュします。 */ export async function getIdToken() { const session = await Auth.currentSession(); return session.getIdToken().getJwtToken(); // string } |
この関数をコンテキストやカスタムフックでラップすれば、アプリ全体から簡単にトークンへアクセスできます。
API 呼び出し時のヘッダー付与
1. Amplify API モジュール使用例
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
import { API } from 'aws-amplify'; import { getIdToken } from './auth'; export async function callProtectedApi(path, init = {}) { const token = await getIdToken(); const request = { ...init, headers: { ...(init.headers || {}), Authorization: `Bearer ${token}`, }, }; return API.get('myapi', path, request); } |
2. axios インターセプタ使用例(既存プロジェクト向け)
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
import axios from 'axios'; import { getIdToken } from './auth'; const api = axios.create({ baseURL: import.meta.env.VITE_API_URL, // Vite 環境変数例 }); api.interceptors.request.use(async config => { const token = await getIdToken(); config.headers.Authorization = `Bearer ${token}`; return config; }); export default api; |
どちらの方法でも、トークンの取得・リフレッシュは Amplify が内部で処理するため、開発者が手動で行う必要はありません。
ローカル開発・本番デプロイと静的コンテンツ配信のベストプラクティス
認証機能をローカルだけで完結させても、本番環境では 環境変数管理 や CI/CD パイプライン が重要です。また、認証済みユーザー限定で S3/CloudFront から静的ファイルを配信する方法も併せて紹介します。
環境変数の管理(.env.local と Amplify 環境)
React はビルド時に .env* ファイルから環境変数を注入できます。Amplify のマルチ環境と合わせるポイントは以下の通りです。
導入文:この表はローカル開発・Amplify dev・Amplify prod それぞれで設定すべきキーと例を示しています。
| キー | ローカル (.env.local) |
Amplify (dev) | Amplify (prod) |
|---|---|---|---|
REACT_APP_API_URL |
http://localhost:4000 |
https://api-dev.example.com |
https://api-prod.example.com |
REACT_APP_REGION |
ap-northeast-1 |
同上 | 同上 |
REACT_APP_USER_POOL_ID |
(自動生成) | us-east-1_XXXXXX |
us-east-1_YYYYYY |
Amplify がデプロイ時に自動で aws-exports.js を切り替えるため、.env* には API エンドポイントや外部サービスのキーだけを保持すれば十分です。
Vercel / Netlify へのデプロイ手順と CI/CD 設定
- GitHub にリポジトリ(例:
https://github.com/your-org/react-cognito-sample)を作成し、コードをプッシュ - Vercel または Netlify のダッシュボードで 「Import Project」 → 対象リポジトリを選択
- ビルドコマンド:
npm run build(Create React App)またはvite build(Vite) - 出力ディレクトリ:
buildまたはdistを設定 - Environment Variables に
.env.localと同等のキーを追加し、シークレットは UI で暗号化保存
CI/CD パイプラインに以下のステップを組み込むと、認証リソースの変更も自動的に反映されます。
|
1 2 3 4 5 6 7 |
# デプロイ前ステージ(例: GitHub Actions) - name: Amplify Deploy run: | npm install -g @aws-amplify/cli amplify pull --yes # 環境設定の取得 amplify push --yes # リソース更新 |
認証済みユーザー向け S3 + CloudFront 配信設定
認可されたユーザーだけがプライベートな静的ファイル(画像・PDF 等)にアクセスできる構成です。導入文で「Cognito の ID トークンを利用して、CloudFront がリクエストを検証する」ことを説明します。
- S3 バケット作成
- 名前例:
myapp-private-assets -
パブリックアクセスはすべて無効化
-
IAM ポリシー付与(認証ロールに追加)
|
1 2 3 4 5 6 |
{ "Effect": "Allow", "Action": ["s3:GetObject"], "Resource": ["arn:aws:s3:::myapp-private-assets/*"] } |
- CloudFront ディストリビューション設定
- Origin に上記 S3 バケットを指定し、Origin Access Identity (OAI) を作成してバケットへの直接アクセスを遮断
-
Cache Policy は「キャッシュキーにヘッダー
Authorizationを含める」ように構成 -
Lambda@Edge でトークン検証(Node.js 18 ランタイム推奨)
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
exports.handler = async (event) => { const request = event.Records[0].cf.request; const authHeader = request.headers.authorization?.[0]?.value; if (!authHeader) return { status: '401', body: 'Unauthorized' }; // Cognito の公開鍵で JWT を検証(省略) const isValid = await verifyCognitoToken(authHeader); if (!isValid) return { status: '403', body: 'Forbidden' }; // トークンが有効ならそのままオリジンへ return request; }; |
この構成により、React アプリから取得した ID トークンを Signed Cookie として CloudFront に送信すれば、プライベートコンテンツへのアクセスが安全に制御できます。
まとめ
- AWS アカウントと Cognito のユーザープール・ID プール を無料利用枠で作成し、最小権限かつ未認証ロールは無効化してセキュリティを確保
- Amplify CLI で
amplify init→amplify add auth→amplify pushと IaC 化すれば、インフラの再現性が向上しチーム開発が楽になる - Amplify UI v6 の
<Authenticator>を組み込み、テーマオブジェクトでブランドカラーに合わせた認証画面を実装できる - React Router v6 の ProtectedRoute と
Auth.currentSession()によるトークン取得・自動リフレッシュで、認可が必要なページや API 呼び出しを安全に保護 - 環境変数は
.env.localと Amplify 環境で分離管理。CI/CD(Vercel/Netlify)ではamplify push --yesをデプロイ前ステップに組み込むと、認証リソースの変更も自動適用できる - S3 + CloudFront のプライベート配信 では Cognito ID トークンを Lambda@Edge で検証し、認可済みユーザーだけが静的コンテンツにアクセス可能になる
上記手順を踏めば、React アプリに対して 堅牢かつスケーラブルな Cognito 認証基盤 を短時間で構築できます。ぜひ実装し、AWS 無料利用枠の中で本番レベルの認証体験をご確認ください。