🔒

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 から:

  1. Cognito サービスにアクセス
  2. 「ユーザープールの作成」をクリック
  3. アプリケーションのタイプを選択
  4. サインインオプションで「メールアドレス」を選択
  5. セキュリティ要件を構成
  6. 必要に応じて MFA や検証方法を設定
  7. ユーザープールの名前を入力して作成

作成後、以下の情報をメモしておきます:

  • 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 でも問題なくできると思います。

以上です。

参考リソース

KA projects

Discussion