AmplifyのAuthメソッドをオーバーライドし、認証前後で処理を追加する
こんにちは。データアナリティクス事業本部 サービスソリューション部の北川です。
今回は、Amplify Authenticatorの内部の仕組みがわからず、追加の処理を実装するのに苦労したので、共有したいと思います。
Amplify Authenticatorについて
AmplifyのAuthenticatorを使用することで、画面の実装含め、認証周りの処理をAmplify側に任せることができます。
import { Amplify } from 'aws-amplify'; import { Authenticator } from '@aws-amplify/ui-react'; import '@aws-amplify/ui-react/styles.css'; import awsExports from './aws-exports'; Amplify.configure(awsExports); const Sample = () => { return ( <Authenticator> {({ signOut, user }) => ( // 認証後に表示するコンポーネント )} </Authenticator> ); } export default Sample;
Authenticatorでラッピングするだけで、簡単に認証処理を実装してくれるので、開発効率が上がります。
Amplify Authメソッドのオーバーライド
Amplifyの認証実行時に、追加の処理が必要な場合は、関数をオーバーライドする必要があります。
Authメソッドを上書きする関数は、以下の種類があります。
- handleSignUp
- handleSignIn
- handleConfirmSignIn
- handleConfirmSignUp
- handleForgotPassword
- handleForgotPasswordSubmit
認証前に処理を追加
公式の例を見ると、ユーザー名とEメールを小文字に変換する処理を追加しています。
import { Amplify, Auth } from 'aws-amplify'; import { Authenticator } from '@aws-amplify/ui-react'; import '@aws-amplify/ui-react/styles.css'; import awsExports from './aws-exports'; Amplify.configure(awsExports); export default function AuthenticatorWithEmail() { const services = { async handleSignUp(formData) { let { username, password, attributes } = formData; // custom username username = username.toLowerCase(); attributes.email = attributes.email.toLowerCase(); return Auth.signUp({ username, password, attributes, }); }, }; return ( <Authenticator services={services} initialState="signUp"> {({ signOut }) => <button onClick={signOut}>Sign out</button>} </Authenticator> ); }
この例では、認証が実行される前に処理を追加して、SignUp()をオーバーライドしています。
認証後に処理を追加
次に認証の実行後に追加する処理について実装します。
この時、上書きする前の関数(ライブラリ)が、本来望んでいた値を返す必要があります。
初期の戻り値
signInに処理を追加せずに、そのまま返す場合、戻り値はPromiseになっています。
戻り値を指定しない場合:
戻り値がPromiseとなり、本来望んでいた値を返していないため、不具合が生じます。
戻り値を指定した場合:
戻り値が本来望んでいた値(Promise)と一致しています。
基本的にtypeScriptではanyを避けたいので、実装例は以下のようになります。型を定義することで、戻り値を返さない場合にエラーを出してくれます。
import { Amplify, Auth } from 'aws-amplify'; import { Authenticator } from '@aws-amplify/ui-react'; import { CognitoUserAmplify } from '@aws-amplify/ui' import '@aws-amplify/ui-react/styles.css'; import awsExports from './aws-exports'; Amplify.configure(awsExports); type FormData = { username: string password: string } const Sample = () => { const services = { async handleSignIn(formData: FormData): Promise<CognitoUserAmplify> { const { username, password } = formData; return Auth.signIn({ username, password, }).then((user) => { console.log('success'); router.push('/'); return user; }) }, } return ( <Authenticator services={services} loginMechanisms={['email']}> {({ signOut }) => <button onClick={signOut}>Sign out</button>} </Authenticator> ); }; export default Sample;
認証が成功した時に、"/"に移動する処理を追加することができました。
もちろんオーバーライド機能によって、エラー時の処理についてもカスタマイズすることが可能です。ちなみにエラー構文を記述しなければ、(Amplifyに)元々備わっていたエラー構文を返します。
まとめ
今回は、Amplifyの認証時の処理をオーバーライドする関数を試してみました。関数のオーバーライドについて知識が浅く、開発時はチームのメンバーに助けてもらいながら、実装しました。また一つ知識が増えたので、ありがたいです。基本的な部分だと思いますが、自分と同じように苦戦している人の助けになればと思います。
ではまた。