【Next.js×Auth.js×Cognito】Amazon Cognitoマネージドログイン使ってみた
はじめに
ログイン画面の作成面倒だな。セキュリティの配慮なるべく減らしたいな。
そんな願いを叶えてくれるかもしれないCognitoマネージドログイン機能を使ってみました。
Amazon Cognitoマネージドログインとは
アプリケーションにログイン機能を簡単に追加するためのサービスです。
Amazon Cognitoに「ホストされたUI」機能は昔からありましたが、ログイン画面のカスタマイズがいまいち不便だったため、結局自分で実装するしかない状況でした。
しかし、2024年にマネージドログイン機能が導入され、文字やボタンの色、ファビコンやページ背景など、細かなところまでカスタマイズ可能になりました。これはうれしいアップデートです。

Auth.jsとは
もともとNextAuthという名前のライブラリでNext.jsに認証機能を組み込むためのOSSでしたが、現在はフレームワークに依存しない形に進化しています。
数多くのプロバイダに対応している点は非常に素晴らしい!もちろんCognitoにも対応しています。
検証概要
以下の手順で作成します。
- Next.jsプロジェクトの作成
- Auth.jsの導入
- Amazon Cognitoの設定
- Cognitoプロバイダの設定
- 動作確認画面の作成
- サインイン画面の日本語化
やってみる
以下のバージョンで実装しています。
- Node.js 22.13.1
- pnpm 9.15.4
- Next.js 15.1.7
- Auth.js 5.0.0 beta
Node.js、pnpmはインストール済み、AWSアカウントは作成済みの前提で進めます。
Next.jsプロジェクトの作成
create-next-appでNext.jsプロジェクトを作成します。
npx create-next-app@latest
プロンプトは以下のようにしました。最後だけNo、他はYesです。
? What is your project named? ... next-auth-cognito
? Would you like to use TypeScript? ... Yes
? Would you like to use ESLint? ... Yes
? Would you like to use Tailwind CSS? ... Yes
? Would you like your code inside a `src/` directory? ... Yes
? Would you like to use App Router? (recommended) ... Yes
? Would you like to use Turbopack for `next dev`? ... Yes
? Would you like to customize the import alias (`@/*` by default)? » No
Auth.jsの導入
公式ページに従います。
インストールコマンドを実行します。
pnpm add next-auth@beta
以下のコマンドで環境変数を作成します。
.env.localファイルが作成され、AUTH_SECRETにランダムな文字が設定されます。
npx auth secret
続いて以下3ファイルauth.ts route.ts middleware.tsを作成します。
import NextAuth from "next-auth"
export const { handlers, signIn, signOut, auth } = NextAuth({
providers: [],
})
import { handlers } from "@/auth"
export const { GET, POST } = handlers
export { auth as middleware } from "@/auth"
これで基本的なセットアップは完了です。
Amazon Cognitoの設定
ここからはAWSを操作します。Amazon Cognitoのユーザープールメニューから「ユーザープールを作成」をクリックします。

アプリケーションタイプは「従来のウェブアプリケーション」を選択します。
アプリケーション名は何でもいいです。

オプションについては要件にあったものを選択してください。
ここでは「メールアドレス」を選択しました。

リターンURLにhttp://localhost:3000/api/auth/callback/cognitoを設定します。ローカル環境で実行するためにhttp://localhost:3000としていますが、本番環境では本番環境用のURLを設定してください。
「ユーザーディレクトリを作成する」をクリックします。

これでユーザプールの作成が完了しました。
次にOpenID Connectのスコープに「プロファイル」を追加します。Auth.jsがログイン時にプロファイルを要求するため、ここで設定しておかないとログイン時にエラーとなります。
アプリケーションクライアントのメニューからアプリケーションクライアント名を選択します。

「ログインページ」タブのマネージドログインページの設定から「編集」をクリックします。

OpenID Connectのスコープの「OIDCスコープを選択」をクリックすると、選択可能なリストが表示されます。その中の「プロファイル」を選択します。

「プロファイル」が追加されたことを確認し、「変更を保存」をクリックします。

Cognitoプロバイダの設定
公式ページに従い、Auth.jsにCognitoの設定を追加していきます。
.env.localに環境変数(AUTH_COGNITO_ID、AUTH_COGNITO_SECRET、AUTH_COGNITO_ISSUER)を設定します。

AUTH_COGNITO_ID、AUTH_COGNITO_SECRETはアプリケーションクライアントに関する情報から確認できます。

AUTH_COGNITO_ISSUERは少しスクロールしたところにあるQuick Setup ガイドの中から確認できます。

次にauth.tsのprovidersにCognitoを設定します。
import NextAuth from "next-auth"
+ import Cognito from "next-auth/providers/cognito"
export const { handlers, signIn, signOut, auth } = NextAuth({
+ providers: [Cognito],
- providers: [],
})
動作確認画面の作成
サインインボタンを作成します。
import { signIn } from "@/auth"
export default function SignIn() {
return (
<form
action={async () => {
"use server"
await signIn("cognito")
}}
>
<button className="border rounded" type="submit">サインイン</button>
</form>
)
}
トップページにサインインボタンとユーザ情報を表示します。
import { auth } from "@/auth";
import SignIn from "./sign-in";
export default async function Home() {
const session = await auth();
return (
<div>
<SignIn />
<div>{ session?.user?.email }</div>
</div>
);
}
動作確認
トップページにボタンを配置したので、ブラウザからhttp://localhost:3000/にアクセスします。

「サインイン」ボタンをクリックするとCognitoのサインイン画面へ移動します。

サインイン画面の日本語化
デフォルトではサインイン画面が英語になっていますが、サインインページのクエリパラメーターにlang=jaを指定することで日本語になります。Auth.jsを使用している場合、signIn関数の引数でクエリパラメータを指定することができます。
import { signIn } from "@/auth"
export default function SignIn() {
return (
<form
action={async () => {
"use server"
+ await signIn("cognito", {}, "lang=ja")
- await signIn("cognito")
}}
>
<button className="border rounded" type="submit">サインイン</button>
</form>
)
}

Cognitoで確認用ユーザを作成し、それを使ってサインインしてみます。
メールアドレスを入力するとパスワード入力画面が表示されました。

初回のサインインではパスワード変更を促されました。

サインインが成功するとアプリ側にリダイレクトされ、セッション情報が取得できていることが確認できました!

まとめ
Amazon Cognitoマネージドログインを使ってみました。
サインイン機能に加え、パスワード変更やアカウント作成機能もマネージドなのは魅力的ですね。
この記事が誰かのお役に立てれば幸いです。
マネージドログイン画面いじってみた
ロゴ画像と背景画像を変更しました。ボタンの色などを調整するとそれっぽい画面に変身しました。

Amazon Cognitoにブランディングデザイナーという機能が用意されていて、コーディングなしでスタイルの変更が行えるのはすごく便利ですね。

Auth.jsがうまく動かないとき
この記事の内容にたどり着くまでにAuth.jsのエラーで苦労しました。
以下のデバッグのオプションに助けられたため紹介しておきます。このオプションを有効にするとリクエスト内容がコンソールに表示されます。レスポンスのエラー内容も確認できます。
import NextAuth from "next-auth"
export const { handlers, signIn, signOut, auth } = NextAuth({
providers: [],
+ debug: true,
})
Discussion