【2023年末: aws-amplify v6対応】ReactでSSO(シングルサインオン)を実装する
情報システム室 進地 です。
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の実装コードのサンプルを示します。
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)から自身の属性情報を取得しようとするとエラーとなる際の確認ポイント