Next.jsでAmplifyのヘッドレス機能を試してみた

2022.07.18

こんにちは。データアナリティクス事業本部 サービスソリューション部の北川です。

今回は、Next.jsのプロジェクトで、Amplify.Providerを使ったヘッドレスの認証管理を試してみました。ヘッドレス機能を使用することで、より柔軟に認証周りの実装を行うことができます。

ちなみに現状Amplifyはドキュメントが二つあるようで、上記のサイトが新しいです。

試してみた

amplify側の設定は、以下のエントリーの「amplify auth」の設定で記述しています。

aws-amplifyをインストールします。

$ yarn add @aws-amplify/ui-react aws-amplify

ユーザー情報の取得

Amplify.Providerでコンポーネントをラッピングすることにより、ページ内で認証状態を取得することが可能になります。

_app.tsx

import "../../styles/globals.css";
import type { AppProps } from "next/app";
import { Authenticator, useAuthenticator } from "@aws-amplify/ui-react";

function MyApp({ Component, pageProps }: AppProps) {
  return (
    <Authenticator.Provider>
      <Component {...pageProps} />
    </Authenticator.Provider>
  );
}

export default MyApp;

ユーザー情報を取得するには、useAuthenticatorを使用します。

公式ドキュメントに倣って、index.tsxを以下のように変更します。

index.tsx

import { useAuthenticator } from "@aws-amplify/ui-react";

const Home = () => {
  const { user, signOut } = useAuthenticator((context) => [context.user]);

  console.log(user);
  return (
    <>
      <h2>Welcome, {user.username}!</h2>
      <button onClick={signOut}>Sign Out</button>
    </>
  );
};

export default Home;

ユーザー情報が取得できています。

認証状態の取得

useAuthenticatorにrouteを指定することで、現在の認証状態を取得できます。

また、useAuthenticatorは、authenticator.providerでラッピングした内部で使用する必要があるので、_app.tsxでそのまま使用することはできません。_app.tsxで使用すると、以下のエラーがでます。

解決方法として、Next.jsでは_app.tsxの上の階層を作成し、MyAppコンポーネントをラッピングします。

import "../../styles/globals.css";
import type { AppProps } from "next/app";
import { Authenticator, useAuthenticator } from "@aws-amplify/ui-react";
import "@aws-amplify/ui-react/styles.css";
import { Amplify } from "aws-amplify";

import awsExports from "../aws-exports";
Amplify.configure(awsExports);

const App = (props: AppProps) => {
  return (
    <Authenticator.Provider>
      <MyApp {...props} />
    </Authenticator.Provider>
  );
};

const MyApp = ({ Component, pageProps }: AppProps) => {
  const { route } = useAuthenticator((context) => [context.route]);

  console.log(route);

  return <Component {...pageProps} />;
};

export default App;

routeの認証状態によって、ページを分岐させるのも容易になります。_app.tsxのMyAppの中を変更します。

  return (
    <>
      {route === "authenticated" ? (
        <Component {...pageProps} />
      ) : (
        // サインインページ
        <Authenticator />
      )}
    </>
  );

認証前

認証後

routeを定義するだけで、認証状態によるページの分岐ができました。

まとめ

今回は、Amplifyのヘッドレス機能を試してみました。useAuthenticatorでは、routeだけでなく、単純に認証しているか確認するauthStateも用意されています。用途によって使い分けれるようになれればと思います。

入社して3ヶ月が経ちました

まだまだ機能一つ実装するだけでも詰まることが多く、周りに助けてもらいながら日々開発に取り組んでいます。 7月前半はバタバタしており、ブログの投稿ができていませんでしたが、気合を入れ直し、自分のためにもアウトプット時間を増やしていきます。

ではまた。