この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。
こんにちは。データアナリティクス事業本部 サービスソリューション部の北川です。
今回は、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の認証時の処理をオーバーライドする関数を試してみました。関数のオーバーライドについて知識が浅く、開発時はチームのメンバーに助けてもらいながら、実装しました。また一つ知識が増えたので、ありがたいです。基本的な部分だと思いますが、自分と同じように苦戦している人の助けになればと思います。
ではまた。