AWS Amplify × Cognito認証
AWS Amplify × Cognito ではじめるシンプルな認証システムの実装
はじめに
このあいだハッカソンに出場した際、インフラとして AWS を採用し、認証は Cognito を用いた email, password 方式に決定しました。そして、フロントから Cognit に認証リクエストを飛ばすために使ったのが AWS Amplify です。
この記事は AWS Amplify を用いた認証についての備忘録です。
※この記事に書いているのは v5 のものです。v6 は参考文献から飛んで違いを確かめてください
AWS Amplify と Amazon Cognito とは
AWS Amplify
フロントエンド開発者向けのフレームワークで、AWS のさまざまなサービスを簡単に利用できるようにするツールセットです。デプロイとかで使うイメージですが、認証でも使えるらしい。
Amazon Cognito
要は認証・認可サービスです。詳しいことは調べてください。
環境構築
1. 必要なパッケージのインストール
npm install aws-amplify
2. AWS Cognito ユーザープールの作成(インフラ側の作業)
AWS Management Console から:
- Cognito サービスにアクセス
- 「ユーザープールの作成」をクリック
- アプリケーションのタイプを選択
- サインインオプションで「メールアドレス」を選択
- セキュリティ要件を構成
- 必要に応じて MFA や検証方法を設定
- ユーザープールの名前を入力して作成
作成後、以下の情報をメモしておきます:
- User Pool ID
- App Client ID (ユーザープールウェブクライアント ID)
Amplify の設定
アプリケーションのエントリーポイントで、Amplify を設定します。
import { Amplify } from "aws-amplify";
Amplify.configure({
Auth: {
region: "ap-northeast-1",
userPoolId: process.env.VITE_APP_USER_POOL_ID, // 環境変数から読み込む
userPoolWebClientId: process.env.VITE_APP_USER_POOL_CLIENT_ID, // 環境変数から読み込む
},
});
環境変数は.env
ファイルに以下のように設定します(Vite プロジェクトの場合):
VITE_APP_USER_POOL_ID=ap-northeast-1_xxxxxxxxx
VITE_APP_USER_POOL_CLIENT_ID=xxxxxxxxxxxxxxxxxxxx
認証機能の実装
サインアップ(ユーザー登録)
import { Auth } from "aws-amplify";
const signUp = async (email, password) => {
try {
const { user } = await Auth.signUp({
username: email,
password,
});
console.log("サインアップ成功:", user);
return user;
} catch (error) {
console.error("エラー:", error);
throw error;
}
};
メールアドレスの確認
サインアップ後、ユーザーにはメールで確認コードが送信されます。そのコードを使って確認を行います。
const confirmSignUp = async (email, code) => {
try {
await Auth.confirmSignUp(email, code);
console.log("確認成功");
return true;
} catch (error) {
console.error("確認エラー:", error);
throw error;
}
};
サインイン(ログイン)
const signIn = async (email, password) => {
try {
const user = await Auth.signIn(email, password);
console.log("サインイン成功:", user);
return user;
} catch (error) {
console.error("サインインエラー:", error);
throw error;
}
};
現在のユーザー情報の取得
const getCurrentUser = async () => {
try {
const userInfo = await Auth.currentAuthenticatedUser();
console.log("現在のユーザー:", userInfo);
return userInfo;
} catch (error) {
console.error("ユーザー取得エラー:", error);
return null;
}
};
サインアウト
const signOut = async () => {
try {
await Auth.signOut();
console.log("サインアウト成功");
return true;
} catch (error) {
console.error("サインアウトエラー:", error);
throw error;
}
};
パスワードリセット
パスワードを忘れた場合の処理も実装しておくとよいでしょう。
// パスワードリセットの開始
const forgotPassword = async (email) => {
try {
await Auth.forgotPassword(email);
console.log("確認コード送信成功");
return true;
} catch (error) {
console.error("パスワードリセットエラー:", error);
throw error;
}
};
// 新しいパスワードの設定
const forgotPasswordSubmit = async (email, code, newPassword) => {
try {
await Auth.forgotPasswordSubmit(email, code, newPassword);
console.log("パスワードリセット成功");
return true;
} catch (error) {
console.error("新パスワード設定エラー:", error);
throw error;
}
};
セキュリティについて
1. 環境変数の使用
当たり前ですが、ユーザープール ID やクライアント ID を直接コードに埋め込まないでください。
2. トークンの保存
signIn すると、自動的に localStorage に userName(ユーザー ID) と idToken が保存されます。引っ張り出す時は以下のようにして引っ張り出してください。
const userId = localStorage.getItem(
`CognitoIdentityServiceProvider.${USER_POOL_CLIENT_ID}.LastAuthUser`
);
const idToken = localStorage.getItem(
`CognitoIdentityServiceProvider.${USER_POOL_CLIENT_ID}.${userId}.idToken`
);
おまけ
こちらは Vue の記事ですが、Google 認証を 選択することもできるらしいです。
公式のページ見ても、特にサポートしているフレームワークの内容など書かれていないので、Vite でも問題なくできると思います。
以上です。
Discussion