🤖

【NextAuth.js】cognitoで複数のサードパーティのIDプロバイダーを使った時に直接ソーシャルログインの画面に遷移する

2023/09/04に公開

はじめに

cognitoで複数のサードパーティのIDプロバイダーを利用している状態で、
NextAuth.jsのCognitoProviderを使ってsignIn関数を以下のように実行すると、
cognitoが用意しているログイン画面に遷移してしまいます。

somefile.tsx
import { signIn } from "next-auth/react";

(...省略)

<Button
  onClick={() => signIn("cognito")}
>
  Google
</Button>


cognitoが用意しているログイン画面

普通のアプリケーションでは、このcognitoの画面が見えるとよくないのでサードパーティのログイン画面に直接遷移する方法を紹介します。

解決方法(1)

前提: Cognitoの単一のアプリケーションクライアントに、複数のサードパーティのIDプロバイダーを登録している場合。

以下のように、signInの第三引数に以下のように設定すればいけます。

somefile.tsx
import { signIn } from "next-auth/react";

(...省略)

<Button
  onClick={() => signIn("cognito", {}, { identity_provider: "Google" })}
>
  Google
</Button>

ここで"Google"のところに指定する値は、Cognitoのサインインエクスペリエンス項目にある
アイデンティティプロバイダーの名前を指定すればOKです。


cognitoのコンソール画面(サインインエクスペリエンス項目)

解決方法(2)

前提: Cognitoの単一のアプリケーションクライアントに、単一のサードパーティのIDプロバイダーを登録して、複数のアプリケーションクライアントを運用している場合。

以下のように[...nextauth].tsファイルに複数のCognitoProviderを登録し、
引数のidの部分がそれぞれユニークになるように設定します。

/pages/api/auth/[...nextauth].ts
import CognitoProvider from "next-auth/providers/cognito";

const defaultCognitoProvider = CognitoProvider({
  id: "cognito",
  clientId: process.env.COGNITO_CLIENT_ID,
  clientSecret: process.env.COGNITO_CLIENT_SECRET,
  issuer: process.env.COGNITO_ISSUER,
  checks: "nonce",
});

const googleCcognitoProvider = CognitoProvider({
  id: "cognito-google",
  clientId: process.env.COGNITO_GOOGLE_CLIENT_ID,
  clientSecret: process.env.COGNITO_GOOGLE_CLIENT_SECRET,
  issuer: process.env.COGNITO_ISSUER,
  checks: "nonce",
});

その上で、signIn関数の引数に上で設定したidを指定すると対応するクライアントが実行されます。

somefile.tsx
import { signIn } from "next-auth/react";

(...省略)

<Button
  onClick={() => signIn("cognito")}
>
  default
</Button>

(...中略)

<Button
  onClick={() => signIn("cognito-google")}
>
  default
</Button>

(1)と(2)とでおすすめの方法

どちらでも同じことが実現できるのですが、おすすめなのは(1)の方法です。理由は、アプリケーションクライアントが1つになるためです。

本題とは関係ないですが、アクセストークンの更新やサインアウトを実装することも考えると(1)の方がおすすめです。それぞれ以下の記事が参考になります。

  • アクセストークンの更新

https://mseeeen.msen.jp/nextauth-cognito-token-refresh/

  • サインアウトの挙動

https://mseeeen.msen.jp/logout-cognito-session-with-nextauth/

加えてIDトークンの検証をする時にも同じアプリケーションクライアントである必要があります。そういった点からも(1)の方法がおすすめです。

おわりに

複数のアプリケーションクライアントを指定した時の
CognitoProvider周りのドキュメントが存在せず(調べた限りですが…)結構苦労しました。

最初は(2)の方法でアプリケーションを作成していたのですが、調べて行くうちに
(1)の方法で作成した方が構成やプログラムもシンプルでいいなと思い採用しました。

誰かのお役に立てれば幸いです。

結局うまくいかなかったけれど試したこと

cognitoのClientへのURLを直接実行する。

以下のようなURLをボタンに設定して遷移するなど試したのですが、NextAuth側のトークンをうまく取得できないため断念しました(あまりガッツリ試していないので、URLの設定とかが間違っているかもです…)。

const googleLoginUrl = `${process.env.NEXT_PUBLIC_COGNITO_ENDPOINT}/oauth2/authorize?identity_provider=Google&redirect_uri=${host}/api/auth/callback/cognito&response_type=CODE&client_id=${clientId}&scope=${scope}`;

https://docs.aws.amazon.com/ja_jp/cognito/latest/developerguide/logout-endpoint.html

GitHubで編集を提案

Discussion