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クラスのメソッドを叩いた後のイベントを起動できますので、知っておくと便利です。

    広告ここから
    広告ここまで
    Home
    Search
    Bookmark