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