🦉

NextAuthでNext.jsに認証機能をサクッと実装するサンプルが無かったので作った

2021/03/29に公開

NextAuth ?

https://next-auth.js.org/

Next.js に認証機能を簡単に実装できるライブラリです。
GitHub, Google, Twitter, Facebook, Apple, Line, … などのアカウントを使用したソーシャルログインをシュッ!っと組み込めます。

作ったもの

Vercel にデプロイしたもの
https://next-auth-sample.vercel.app/

ソース
https://github.com/TakahiroHimi/NextAuth-sample
実行手順は README をご覧ください。

実行するとSign inボタンが表示されるので押下します。


Sing In with GitHubボタンが表示されるので押下します。


GitHub の Sign in ページへ移動するのでログインします。


localhost へリダイレクトされ、ブラウザに自分のアカウント情報と取得したアクセストークンが表示されます。


取得したアクセストークンは以下の記事で紹介している GitHubAPI から Issue を取得する際のトークンに使用できますので、良かったらお試しください。
https://zenn.dev/thim/articles/3d98b275df79939a003b#variables%2Cheaders-を設定



上記操作で発行されたアクセストークンは以下のページから無効化できます。
https://github.com/settings/applications

簡単に解説

今回作成したソースはindex.tsx[...nextauth].ts_app.tsxの 3 ファイルのみです。
最後の_app.tsxについては Provider を設定するだけなので割愛し、その他2ファイルで何をしているか簡単に解説します。

pages/index.tsx
import { signIn, signOut, useSession } from "next-auth/client";

const Page = () => {
  const [session, loading] = useSession();                          //👈ポイント①

  return (
    <>
      {!session && (
        <>
          {loading ? (
            <>Loading ...</>
          ) : (
            <>
              Not signed in <br />
              <button onClick={() => signIn()}>Sign in</button>    {/* 👈ポイント② */}
            </>
          )}
        </>
      )}
      {session && (
        <>
          Signed in as <img src={session.user.image ?? ""} width="50px" />   {/* 👈ポイント③ */}
           {session.user.name} <br />
          AccessToken : {session.accessToken} <br />
          <button onClick={() => signOut()}>Sign out</button>      {/* 👈ポイント④ */}
        </>
      )}
    </>
  );
};
  • ポイント ①useSessionで session 情報と loading 状態を保持する変数を作成
  • ポイント ②signIn()実行で SignIn
  • ポイント ③:SingIn 後は session 情報取得可能
  • ポイント ④singOut()実行で SignOut


pages/api/auth/[...nextauth].ts
import NextAuth from "next-auth";
import Providers from "next-auth/providers";
import { GenericObject } from "next-auth/_utils";

export default NextAuth({
  providers: [                                                      //👈ポイント①
    Providers.GitHub({
      clientId: process.env.GITHUB_ID ?? "",
      clientSecret: process.env.GITHUB_SECRET ?? "",
    }),
  ],
  callbacks: {
    async jwt(token, user, account, profile, isNewUser) {           //👈ポイント②
      if (account?.accessToken) {
        token.accessToken = account.accessToken;
      }
      return token;
    },
    async session(session, token) {                                 //👈ポイント③
      session.accessToken = (token as GenericObject).accessToken;
      return session;
    },
  },
});
  • ポイント ①providersを設定
    サンプルでは GitHub を使用していますが、Google や Twitter を使用する場合もここで同様に設定します。
  • ポイント ②:JWT が作成・更新された時に実行する処理を記述
    少しややこしいのですが、token.accessToken に SingIn 時発行した accessToken を設定しています。
  • ポイント ③:セッションがチェックされた時に実行する処理を記述
    今度は session.accessTokentoken.accessToken の値(ポイント ② で用意しておいたもの)を設定しています。

callbacks について補足

簡単に言うと何かのアクションが実行されたタイミングで発火させたい処理を記述します
上記ではjwtsession以外割愛しましたが、他にもsignInredirectがあります。

  • singIn:サインイン時に実行したい処理を記述
  • redirect:リダイレクト時に実行したい処理を記述

サンプルコードには全ての callbacks にconsole.logを入れてますので、コンソールを眺めながら画面を触ると各コールバックがどのタイミングで実行されるかわかると思います。
公式ページにも英語ですがわかりやすい解説がありますので、一度読んでみると理解が深まります。
https://next-auth.js.org/configuration/callbacks

最後に

NextAuth は簡単に認証機能を実装できるので気に入っているのですが、日本語情報や TypeScript でのサンプルが少ないので記事にしました。
今回は簡単な例でしたが、取得した認証情報を使ってあれこれするサンプルも今後作りたいと思います。

追記
作りました
https://zenn.dev/thim/articles/9ff415100b892d23aa59

Discussion