ISIRMT Logo

特定のアカウント以外はログインでエラーが出るようにする【Next.js + Auth.js】

Next.js
Auth.js
シリーズ『isirmt.com v2 制作メモ』

Auth.js(NextAuth)でシングルサインオン(SSO)を実現する際,ログインできるユーザーを絞りたい場合があるかと思われます.

例えば,特定のユーザーのみにWEBアプリケーションを提供したい場合など...

Next.jsであればlibディレクトリにAuth.jsのコンフィグを記述しますが,callbacksではbooleanを返すことができるメソッドがあり,認証で失敗を返すことができるようになっています.

<無題>ts
export const { auth, handlers, signIn, signOut } = NextAuth({
  // 略
  callbacks: {
    async signIn({ profile }) {
      return isAllowedEmail(profile?.email);
    },
  },
});

ポートフォリオの実装では,Googleアカウントを使ったSSOにしているのでメアドが取得できます.このメアドが許可されているのかを判定しています.返却されるものはtrueまたはfalseです.

signInメソッドでは次のような挙動をします

  • true: サインインのフローの継続
  • falseまたはエラーのスロー: フローを中断し,エラーページへリダイレクト

エラーページはカスタムできます.

/errorページへリダイレクトts
export const { auth, handlers, signIn, signOut } = NextAuth({
  // 略
  pages: {
    error: "/error",
  },
});

ちなみに執筆時点ではカスタムエラーページが無いので,また実装します.

おまけ

isAllowedEmail関数を記載

<無題>ts
export const isAllowedEmail = (email: string | null | undefined) => {
  const allowedEmailsEnv = process.env.ADMIN_ALLOWED_EMAILS || "";
  const allowedEmails = allowedEmailsEnv
    .split(",")
    .map((e) => e.trim().toLowerCase())
    .filter(Boolean);

  if (!email) return false;
  const normalizedEmail = email.trim().toLowerCase();
  return allowedEmails.includes(normalizedEmail);
};

環境変数にADMIN_ALLOWED_EMAILSを設け,カンマ区切りでメアドを読みだしています.メアドはLowerCaseへ変換した上で比較を行っています.

個人サイトなら多分これで十分だと思います

あとは間違って公開しないことだけ気を付けておけば大丈夫かと思います.

関連記事