AWS Amplifyで、`withAuthenticator`と`Auth.signOut`を併用する
AWS AmplifyのSDK・ライブラリを使うと、認証系のUIや操作をほとんど自分で実装する必要がなくなります。 ただし、任意のUIライブラリ(BootstrapやMaterial UIなど)でAuth系の操作を行いた […]
目次
AWS AmplifyのSDK・ライブラリを使うと、認証系のUIや操作をほとんど自分で実装する必要がなくなります。
import type { AppProps } from 'next/app'
import Amplify from 'aws-amplify';
import { withAuthenticator } from '@aws-amplify/ui-react'
import amplifyConfig from '../src/aws-exports'
Amplify.configure({ ...amplifyConfig, ssr: true });
function MyApp({ Component, pageProps }: AppProps) {
return (
<div id="container">
<Component {...pageProps} />
</div>
)
}
export default withAuthenticator(MyApp)
ただし、任意のUIライブラリ(BootstrapやMaterial UIなど)でAuth系の操作を行いたい場合、「Auth.signOut
を実行したのに、ログイン画面に戻らない」現象が発生します。
これは、withAuthenticator
の中で参照しているStateの更新が、Auth.signOut
を実行するだけでは更新されないためです。
対処法: Hub.dispatch
でイベントを手動で送る
Amplifyのui-componentでは、Hub.dispatch
を使ってログインや追加認証などのイベントが送られています。そこで、内部で使われている実装と同じものを用意することで、Auth.signOut
実行時にStateを正しく更新できるようにします。
まず、内部で利用されているhelperを複製します。exportしてくれていたら助かるので、そのうちGitHubに突撃しているかもしれません。
import {
AuthState,
UI_AUTH_CHANNEL,
AUTH_STATE_CHANGE_EVENT,
AuthStateHandler,
} from '@aws-amplify/ui-components';
import { Hub } from 'aws-amplify';
export const dispatchAuthStateChangeEvent: AuthStateHandler = (
nextAuthState: AuthState,
data?: object
) => {
Hub.dispatch(UI_AUTH_CHANNEL, {
event: AUTH_STATE_CHANGE_EVENT,
message: nextAuthState,
data,
});
};
あとはAuth.signOut
の後にこれをよびだします。
import Amplify, {Auth} from 'aws-amplify';
import { withAuthenticator } from '@aws-amplify/ui-react'
import { AuthState } from '@aws-amplify/ui-components';
...
<button onClick={() => {
Auth.signOut({
global: true
}).then(() => {
push('/')
dispatchAuthStateChangeEvent(AuthState.SignedOut)
})
}}>
Logout
</button>
TypeScript的な話としては、dispatchAuthStateChangeEvent
の引数がAuthState
のEnumなので、@aws-amplify/ui-components
からimportする必要があることに注意です。
似たような要領でAuth
クラスのメソッドを叩いた後のイベントを起動できますので、知っておくと便利です。