情報システム室 進地 です。
2023年10月に途中まで実装していたaws-amplifyを使ったReactでのSSO処理を、先日実装再開したところaws-amplifyがv6にバージョンアップし色々変わっていて難儀しました。
このエントリーでは、aws-amplify v6を使ったReactでのSSO実装を記述します。
前提
既にAzureAD等でCognitoユーザプールとの接続設定はできているものとします。 私は、Amazon Cognito user poolの外部IdPとしてAzure ADを設定してみたの記事を参考に設定しました。
Reactコードサンプル
aws-amplify v6によるSSOの実装コードのサンプルを示します。
src/App.js
import React, { useState, useEffect } from 'react'
import AWS from 'aws-sdk';
import { CircularProgress, Box, Button } from "@mui/material";
// 認証にはAmplify Authを利用する
import { Amplify } from 'aws-amplify';
import { Hub } from 'aws-amplify/utils';
import {
signInWithRedirect,
fetchUserAttributes,
getCurrentUser,
signOut
} from 'aws-amplify/auth';
import awsconfig from './aws-exports';
Amplify.configure(awsconfig);
function App() {
const [user, setUser] = useState(null);
const [userAttributes, setUserAttributes] = useState(null);
const [authInProgress, setAuthInProgress] = useState(false);
useEffect(async () => {
setAuthInProgress(true);
const unsubscribe = Hub.listen("auth", (data) => {
const { payload } = data;
switch (payload.event) {
case "signedIn":
getUser();
break;
case "signedOut":
setUser(null);
setUserAttributes(null);
break;
default:
console.log(payload);
}
});
getUser();
return unsubscribe;
}, [])
const getUser = async () => {
try {
const currentUser = await getCurrentUser();
const currentUserAttributes = await fetchUserAttributes();
setUser(currentUser);
setUserAttributes(currentUserAttributes);
setAuthInProgress(false);
} catch (err) {
console.log("Not signed in");
setUser(null);
setUserAttributes(null);
setAuthInProgress(true);
await signInWithRedirect();
}
};
return (
<Box>
{authInProgress ? (
<Box>
<CircularProgress />
</Box>
) : (
{user && (
<Box>
<Button onClick={async () => await signOut()}>
サインアウト ({userAttributes?.email})
</Button>
</Box>
)}
)}
</Box>
);
}
export default App;
v5からの主な変更点
Hub
はaws-amplify/utils
に、signInWithRedirect
などのAuth関連の関数はaws-amplify/auth
に移動しています。また、Hub.listen
のインタフェースも変わっていますので注意が必要です(ハイライト部25〜27行)。
getUser
関数でユーザ情報の取得を試み、取得できなければサインインしていないと判断して、catch節でsignInWithRedirect
を呼び出して、IdPのログインを促しています。
ハマりポイント
fetchUserAttributes
でメールアドレスなどを取得するには、Cognitoユーザプールのアプリケーションクライアント設定でaws.cognito.signin.user.admin
スコープの追加が必要です。
See Also: Flutter Amplifyでアプリ(iOS)から自身の属性情報を取得しようとするとエラーとなる際の確認ポイント