【Supabase】Next.jsでGoogleソーシャルログインを実装する方法(後編)
前編と後編に分けて、SupabseでGoogle ソーシャルログインを実装する方法をまとめます。後編ではSupabaseによるGoogle ソーシャルログインの実装を行います。


サムネイルはUnsplashのSilas Köhlerが撮影した写真
はじめに
前編では、「Googleログイン」ボタンについて解説しました。後編では、「Googleログイン」ボタンとSupabaseを組み合わせて、ソーシャルログイン(Social Login)を実装する手順を解説します。
本記事で解説する内容
- Googleが提供している「Googleでログイン」ボタンの種類や実装方法(前編)
- Supabaseを使ったGoogleでのSocial Loginの実装方法(後編)←本記事
前編はこちらです。
結論
- 本記事で解説するソースコードはこちらにあります。
- 公式ドキュメントはこちらです
- https://supabase.com/docs/guides/auth/social-login/auth-google?queryGroups=platform&platform=web#one-tap-with-nextjs
- 基本はドキュメント通りに作業すれば実装できますが、一部前提知識がないとわかりにくい箇所があるので、補足しながら解説します
前提
- Next.js用の認証チュートリアルの「3Write utility functions to create Supabase clients」まで完了していること
- @supabase/supabase-js @supabase/ssrがインストール済み
- 環境変数を設定済み(NEXT_PUBLIC_SUPABASE_URL、NEXT_PUBLIC_SUPABASE_ANON_KEY)
- supabaes clientを実装済み(client/serverともに)
- Supabaseの「User Management Starter」を実行済み
- 「SQL Editor」>「Quickstarts」>「User Management Starter」


補足:
- 本記事ではサーバサイドでの認証処理を行っていないので、ミドルウェアは実装しなくても動きます。サーバサイドで認証処理をする際は、ミドルウェアも導入してください。
- 認証情報を保存するデータベースのセットアップは「User Management Starter」テンプレートを使用して行います。セットアップ後、必要に応じてテーブルスキーマは変更できます。
環境準備
Google Cloud側の設定
今回のSocial Loginでは、GoogleをIdpとして利用します。まずはGoogle Cloudでの設定を行っていきます。公式ドキュメントはこちらです。
1. プロジェクトを構成する(初回利用時のみ)
Google CloudのAuth Platformでプロジェクトの構成を行います。
開始をクリックします。

アプリ名とユーザサポートメールを入力します。

対象に「外部」を選択します。

連絡先情報を入力します。

ポリシーに同意します。

作成をクリックすると、プロジェクトが構成されます。

2. OAuth クライアントの作成
「OAuthクライアントを作成」をクリックします。

以下のデータを入力して、作成をクリックします。今回はローカル環境でテストをします。本番環境にデプロイする際は、本番環境のドメインも追加してください。
- アプリケーションの種類:ウェブアプリケーション
- 名前:任意
- 承認済みのJavaScript生成元
- http://localhost
- http://localhost:3000
- 承認済みのリダイレクトURI
- http://localhost
- http://localhost:3000
補足:localhostとlocalhost:3000を両方追加する理由
https://developers.google.com/identity/gsi/web/guides/get-google-api-clientid?hl=ja
キーポイント: ローカルテストまたは開発の場合は、
http://localhost
とhttp://localhost:<port_number>
の両方を追加します。

クライアントIDをコピーします。

Supabase側の設定
Supabaseのダッシュボードから、先ほどコピーしたクライアントIDを設定します。「Authentication」>「Sign In/Up」>「Google」で遷移します。
Client IDsに先ほどコピーしたクライアントIDをペーストして、保存します。

Googleログインボタンの実装
HTMLでのGoogleログインボタンの実装
コード
'use client';
import { createClient } from '@/utils/supabase/client';
import { useRouter } from 'next/navigation';
import Script from 'next/script';
import { useEffect } from 'react';
// グローバルな型定義を追加
declare global {
interface Window {
handleSignInWithGoogle: (response: GoogleResponse) => Promise<void>;
}
}
interface GoogleResponse {
credential: string;
}
export const HtmlBaseLoginButton = () => {
const router = useRouter();
// コンポーネントがマウントされる時にコールバックを設定
useEffect(() => {
window.handleSignInWithGoogle = async (response: GoogleResponse) => {
const supabase = createClient();
try {
const { data, error } = await supabase.auth.signInWithIdToken({
provider: 'google',
token: response.credential,
});
console.log(data);
router.refresh();
router.push('/account'); // ログイン後のリダイレクト先
} catch (error) {
console.log(error);
}
};
// クリーンアップ関数
return () => {
// delete window.handleSignInWithGoogle;
delete (window as any).handleSignInWithGoogle;
};
}, []);
return (
<>
<Script
src='https://accounts.google.com/gsi/client'
strategy='afterInteractive'
/>
);
};
解説
Scriptタグで「Googleログイン」ボタンをレンダリングするためのスクリプトを読み込んでいます。このサンプルコードではコンポーネント内に定義していますが、Layout.tsxなどに移してもいいと思います。
<Script
src='https://accounts.google.com/gsi/client'
strategy='afterInteractive'
/>
Googleボタンの見た目やサインイン方法などを定義しています。HTMLコードはGoogleが提供しているこちらを使用して生成しています。
<div
id='g_id_onload'
data-client_id={process.env.NEXT_PUBLIC_GOOGLE_CLIENT_ID}
data-context='signin'
data-ux_mode='popup'
data-callback='handleSignInWithGoogle'
data-itp_support='true'
data-use_fedcm_for_prompt='true'
></div>
<div
className='g_id_signin'
data-type='standard'
data-shape='pill'
data-theme='outline'
data-text='signin_with'
data-size='large'
data-logo_alignment='left'
></div>
Scriptタグで読み込んだGoogleのコードが関数を呼び出せるようにするために、コールバック関数をグローバルに登録します。
window.handleSignInWithGoogle = async (response: GoogleResponse) => {
参考:https://supabase.com/docs/guides/auth/social-login/auth-google#google-pre-built
Create a
handleSignInWithGoogle
function that takes theCredentialResponse
and passes the included token to Supabase. The function needs to be available in the global scope for Google's code to find it.
Googleから返却されたIDトークン(credential)をsupabaseに渡します。これをもとに、SupabaseがGoogleとやりとりをして、認証やセッションの払い出しを行います。
const { data, error } = await supabase.auth.signInWithIdToken({
provider: 'google',
token: response.credential,
});
補足:HTMLコードを生成ページの使い方
以下のデータ入力します。
- クライアントID:作成したOAuth ClientのクライアントID(サンプルコードでは環境変数で置き換えています。)
- データコンテキスト:ログイン
- コールバック関数:任意の関数名(サンプルコードではhandleSignInWithGoogle)
- グローバル(windowオブジェクト)に定義されている必要があります。

有効にするログイン方法の選択と、見た目のカスタマイズを行います。サンプルコードでは、One Tapと「Googleでログイン」ボタンの両方を有効にしています。

生成したコードをコピーして使用します。

JavaScriptでの「Googleでログイン」ボタンの実装
コードはこちらです。解説はHTMLで実装したものとほぼ同じなので割愛します。
動作確認
開発サーバを起動し、認証の動作確認をします。右上にOne Tapのポップアップ、中央に「Googleでログイン」ボタンが表示されます。どちらからでもログイン可能です。(Next.jsのエラーは本題とは関係がないので、無視します。)

ログインに成功すると、/account画面にリダイレクトします。ログインしたユーザのプロフィール画像とメールメールアドレスが表示されていれば成功です。

SupabaseのダッシュボードからもGoogleでログインしているセッションが払い出されたことが確認できます。

以上で、SupabaseでGoogle Social Loginの実装は完了です。
おわりに
本記事では、SupabaseでGoolgeを認証プロバイダーとしたSocial Loginの実装を行いました。Googleが提供するスクリプトを使うことで、UXのよいログインフローを少ないコードで実装することができます。
私は最初にSupabaseのチュートリアルをやった際に、どこまでがGoogle/Supabaseが提供しているものか、またGoogleが提供しているログイン方法を知らず、全体を理解するのに時間がかかりました。
この記事が同じような方の理解の助けになれば幸いです。フィードバックやコメントも大歓迎です。🦙
最後までご覧いただきありがとうございました。

通りすがりのラマ🦙
このブログでは、個人開発で得た知見や、興味のあるテクノロジー、時々デザインに関する記事を執筆します。 日々公開されている情報に助けられているので、自分が得た知見も世の中に還元していければと思います。 解決できないバグに出会うと、つばを飛ばします。🦙 経歴:情報工学部→日系SIer→外資系IT企業 興味:Webアプリケーション開発、Webデザイン 趣味:個人開発、テニス