はじめに
cognito の ユーザープール認証について調べたのでメモしておきます。
ユーザープール認証フローの選択
ADMIN_USER_PASSWORD_AUTH
サーバーサイドでの認証で使用します。
CUSTOM_AUTH
チャレンジと、レスポンスの確認が 3 つの AWS Lambda トリガーを通じて制御される。
(TODO)
USER_PASSWORD_AUTH
ユーザー名(メールアドレス)とパスワードをベースとした認証方式。
USER_SRP_AUTH
SRPフローはネットワーク経由でパスワードを送信しないため USER_PASSWORD_AUTH よりもセキュア。
USER_PASSWORD_AUTH を使用するよりは USER_SRP_AUTH を選択したい。
SRP(Secure Remote Password)については以下の記事がシンプルでした。
本題 USER_PASSWORD_AUTH vs USER_SRP_AUTH
USER_PASSWORD_AUTH のリクエスト
Amplify.configure({
Auth: {
authenticationFlowType: "USER_PASSWORD_AUTH",
...
USER_SRP_AUTH のリクエスト
Amplify.configure({
Auth: {
authenticationFlowType: "USER_SRP_AUTH",
...
USER_SRP_AUTH フローによる認証(React.js)
-
ユーザープールにユーザーを登録しておく
-
アプリクライアントの認証フローの設定から
ALLOW_USER_SRP_AUTH
を有効にする。 -
パッケージをインストール(
npm install aws-amplify
) -
実装
App.jsx
import { useState } from "react";
import { Amplify, Auth } from "aws-amplify";
// https://docs.amplify.aws/lib/auth/start/q/platform/js/#configure-your-application
Amplify.configure({
Auth: {
region: "ap-northeast-1",
userPoolId: "xxxxxxxx",
userPoolWebClientId: "xxxxxxxxxxxxxxxxx",
authenticationFlowType: "USER_SRP_AUTH",
},
});
function App() {
const [username, setUsername] = useState("");
const [password, setPassword] = useState("");
const login = async () => {
const user = await Auth.signIn(username, password);
if (user.challengeName === "NEW_PASSWORD_REQUIRED") {
// アカウントステータスが「FORCE_CHANGE_PASSWORD」の場合同じパスワードで設定を上書きし、「CONFIRMED」に変更する
Auth.completeNewPassword(user, password);
}
// この時点で local storage に認証情報が格納される
console.log(JSON.stringify(user, null, 2));
};
const logout = async () => {
await Auth.signOut();
};
return (
<div className="App">
<input type="text" onChange={(e) => setUsername(e.target.value)} />
<input type="text" onChange={(e) => setPassword(e.target.value)} />
<button onClick={login}>login</button>
<button onClick={logout}>logout</button>
</div>
);
}
export default App;
ちなみに認証トークンはローカルストレージに保存されます。(XSSに気をつけよう)
以下を参考に実装してます。