GoogleとAppleのネイティブサインインを React アプリに実装し、 Supabase Authでバックエンドを構築しましょう, そして同じUIをラップします。 Capacitor モバイルブラウザのリダイレクトに悩まされることもありません。 Capgo ソーシャルログイン (@capgo/capacitor-social-login) handles the native provider sheets; you exchange the provider ID token for a Supabase session with signInWithIdToken.
この記事では、既存の Supabase + Social Login ガイドを拡張し、 React + Vite の完全な walkthrough(プロジェクト構成、プロバイダー、ルート、Capacitor の連携)を提供します。プロバイダーのダッシュボードやプラットフォームキーについては、引き続き Supabase連携ドキュメント および Google + Supabase の一般的なセットアップ を参照してください。関連記事: Capacitor を使った Google サインイン, Capacitor を使った Apple サインインや Capacitor での認証オプション.
目次
- 構築する内容
- 認証フローの全体像
- React (Vite) アプリケーションのベース作成
- Supabase プロジェクトと Google プロバイダーの設定
- Supabase でのプロバイダー設定
- Social Login プラグインの初期化
- Supabase クライアントと React 認証レイヤー
- ログインUIと保護されたルート
- ReactアプリにCapacitorを追加する
- プラットフォームの設定
- RLSによるデータベースアクセス
- 既知の問題とトラブルシューティング
- セキュリティ上の考慮事項
構築する内容
- ある Vite + React + TypeScript サインインボタンとログイン後のデバッグビューを備えたWebアプリ
- Supabase Auth ネイティブで作成されたセッション Google (およびオプションの Apple) IDトークン)
- 同じbundleが以下で動作します Capacitor iOSおよびAndroid上で
- nonce安全なGoogleフロー(以下に準拠) pluginのサンプルアプリ
認証フローの全体像
を使用すると、 @capgo/capacitor-social-login、モバイルアプリは 決して 依存する signInWithOAuth WebView内でのリダイレクトに依存します。ネイティブの SDK は IDトークンを返します。Supabaseがこれを検証し、独自のJWTを発行します。

オンラインに ウェブの場合でも、同じプラグインを使用できます(詳細は Googleウェブ設定を参照)。後でブラウザへのフォールバックを追加する場合は、ルーターでOAuthのリターンURLを処理してください。
ベースとなるReact (Vite) アプリケーション
新規アプリの作成(または既存のReactコードベースの再利用):
bun create vite capgo-supabase-auth --template react-ts
cd capgo-supabase-auth
bun install
bun add @supabase/supabase-js @capgo/capacitor-social-login react-router-dom @capacitor/core
開発サーバーの起動:
bun run dev

ターゲットフォルダの構成:

環境変数の追加先: .env.local (機密情報は絶対にコミットしないでください):
VITE_SUPABASE_URL=https://your-project-ref.supabase.co
VITE_SUPABASE_ANON_KEY=your-anon-public-key
VITE_GOOGLE_WEB_CLIENT_ID=your-web-client-id.apps.googleusercontent.com
VITE_GOOGLE_IOS_CLIENT_ID=your-ios-client-id.apps.googleusercontent.com
VITE_APPLE_SERVICE_ID=com.yourapp.signin
VITE_SUPABASE_APPLE_CALLBACK_URL=https://your-project-ref.supabase.co/functions/v1/apple-signin-callback
Social LoginでSupabaseを使う理由
Supabaseは 認証機能内蔵の強力なBaaSを提供し、 @capgo/capacitor-social-login pluginはiOS、Android、Webプラットフォームでネイティブなソーシャル認証を実現します。Supabaseとの連携を強化するには、 @capgo/capacitor-supabase ネイティブの認証ヘルパーとJWTアクセスを追加します。これらを組み合わせることで、以下が可能になります:
- シームレスなソーシャル認証
- セキュアなトークン管理
- クロスプラットフォーム対応
- リアルタイムなデータベース連携
- 組み込みのユーザー管理
前提条件
開始する前に、以下を確認してください:
- Capacitor プロジェクトのセットアップ
- Supabaseのアカウントとプロジェクト
- 選択したソーシャルプロバイダー(Google、Apple、Facebook)のデベロッパーアカウント
ステップ 1: Social Login プラグインのインストールと設定
まず、Capgo Social Login プラグインをインストールします:
bun add @capgo/capacitor-social-login
実行 bunx cap sync その後 Capacitor とネイティブプラットフォームを次に追加します: ReactアプリにCapacitorを追加する。以下の Vite 専用のチュートリアルは、そのステップの前のブラウザ環境でも動作します。
詳細については、 ソーシャルログイン と Supabase プラグインの各ページで、プラットフォームごとの設定を確認してください。
ステップ 2: Supabase プロジェクトのセットアップ

Supabase プロジェクトの作成と設定
-
Supabase プロジェクトを作成する:
- 以下に移動します: supabase.com およびサインアップ/サインイン
- クリック 「新規プロジェクト」
- 組織を選択
- 以下を入力 プロジェクト名 (例: “MyApp Auth”)
- 以下を設定します: データベースのパスワード (安全に保管してください)
- 次を選択: リージョン (ユーザーに最も近い場所を選択)
- クリック 「新規プロジェクトを作成」
-
プロジェクトの認証情報を取得:
- 作成後、以下へ移動します: 設定 > API
- 以下の情報をコピーしてください: プロジェクトURL (例:
https://your-project-ref.supabase.co) - 以下の情報をコピーしてください: anon public API キー
- アプリで使用するため、これらを保存しておいてください
認証設定の構成
-
一般的な認証設定を行います:
- 以下に移動します: 認証 > 設定
- 未満 全般設定:
- 設定 サイトURL アプリのURLを入力(例:
https://yourdomain.comまたはhttp://localhost:3000開発用) - 追加の リダイレクトURL が必要な場合:
http://localhost:3000 https://yourdomain.com capacitor://localhost (for mobile apps)
- 設定 サイトURL アプリのURLを入力(例:
-
メール設定を構成 (任意ですが推奨):
- 未満 SMTP設定メールプロバイダーを設定してください
- これにより、メール確認やパスワードリセットが可能になります
- 開発時は、組み込みのメールサービスを利用できます
ソーシャル認証プロバイダーを有効にする
- プロバイダーセクションにアクセスし、:
- 以下に移動します: Authentication > Providers に移動します。 Supabase dashboardを開きます
- 利用可能なソーシャルプロバイダーの一覧が表示されます
- 各プロバイダーには 有効にする トグルと設定オプション
それでは、各ソーシャルプロバイダーの詳細設定を行っていきましょう。
ステップ 3: Supabase でソーシャルプロバイダーを設定する
Supabase で Google 認証を設定する
まず、Google OAuth の認証情報を取得します。
こちらの Google 設定ガイドに従ってください: Google 認証の設定
このガイドの内容:
- Google Cloud プロジェクトの作成
- Web、iOS、Android 用の OAuth 2.0 認証情報の作成
- 同意画面の設定
- 必要な Client ID とシークレットの取得
Googleの設定完了後、Supabaseで設定してください:
最初のアップデートを送信するには、 Supabase + Google の総合ガイド 各ダッシュボードのクリック箇所のスクリーンショットは
- SupabaseでGoogleプロバイダーを有効にする:
- Supabaseダッシュボードで、 Authentication > Providers に移動します。
- 次を探して、 Google のスイッチを ON
- 次を追加します: Web, iOSとや Android Google Cloudで作成したクライアントID(提供していないプラットフォームはスキップ)
- クリック 保存
このReactチュートリアルで重要なポイント: を使用する場合 signInWithIdToken を使用して @capgo/capacitor-social-login、次のようにします 決して OAuthが必要です クライアントシークレット またはGoogleのコールバックURLフィールドが必要です。各プラットフォームからのトークン検証時にSupabaseが受け入れられるすべてのクライアントIDを登録してください。
SupabaseでのApple Authenticationの設定
Appleの認証情報を取得します:
詳細なApple設定ガイドに従ってください: Apple Authenticationの設定
このガイドの内容:
- Apple Developerアカウントの設定
- App IDとService IDの作成
- Sign in with Apple機能の設定
- 必要なプライベートキーの生成
- iOS、Android、Web向けのプラットフォーム別設定
Appleの設定完了後、Supabaseで以下の設定を行ってください:
- SupabaseでAppleプロバイダーを有効にする:
- 以下に移動します: Authentication > Providers に移動します。 を切り替えて Apple ON
- 設定を入力してください:
- クライアントID:両方のプラットフォームをリリースする場合は、iOS App IDとApple Service IDをカンマ区切りで入力してください(例:
com.yourapp,com.yourapp.signin)。iOSトークンはApp IDのaudienceを使用し、AndroidとWebはService IDを使用します。詳細は SupabaseでのApple認証全般. - 本チュートリアルの
signInWithIdTokenフローでは、@capgo/capacitor-social-login、次のようにします 決して Appleプロバイダー設定に、OAuthクライアントシークレットまたはSupabaseのOAuthコールバックURLが必要です。
- クライアントID:両方のプラットフォームをリリースする場合は、iOS App IDとApple Service IDをカンマ区切りで入力してください(例:
- クリック 保存
注意: Apple認証の設定は、Service ID、秘密鍵、プラットフォーム固有のリダイレクトURLなど、Apple独自の要件があるため最も複雑です。各プラットフォームのドキュメントを注意深く確認してください。
SupabaseでのFacebook認証の設定
Facebookの認証情報を取得:
Facebookの設定に関する完全ガイドはこちら: Facebook認証の設定方法
このガイドの内容:
- Facebook Developerアカウントとアプリの作成
- Facebook Login製品の追加
- OAuthリダイレクトURIの設定
- App ID、App Secret、Client Tokenの取得
- iOSおよびAndroid向けのプラットフォーム別設定
Facebookの設定完了後、Supabaseで以下の設定を行ってください:
- SupabaseでFacebookプロバイダーを有効にする:
- 以下に移動します: Authentication > Providers に移動します。 を切り替えて Facebook ON
- 設定を入力してください:
- クライアントID:Facebook App ID
- クライアントシークレット:Facebook App Secret
- リダイレクトURL:
https://your-project-ref.supabase.co/auth/v1/callback(自動入力)
- クリック 「保存」
重要: SupabaseのコールバックURL ("https://your-project-ref.supabase.co/auth/v1/callback") をFacebookアプリの 有効なOAuthリダイレクトURI に必ず追加してください(Facebook Login設定内)。
Supabase設定に関する重要な注意点
行レベルセキュリティ (RLS):
- 認証の設定後、テーブルのRLSを有効にしてください
- 以下に移動します: Database > Tables を切り替えて RLSを有効にする 各テーブルに対して
- 認証済みユーザーに基づいたデータアクセス制御用のポリシーを作成します
ユーザー管理:
- 認証済みユーザーの確認: Authentication > Users
- 認証イベントの監視: Authentication > Logs
- メールテンプレートの設定: Authentication > Email Templates
設定のテスト:
- Supabase内蔵の認証テストツールを使用します
- 以下に移動します: Authentication > Users をクリックし、 「ユーザーを招待」 でメールフローをテストします
- チェック: ログ 認証エラーを確認するセクション
ステップ 4: Social Login プラグインの設定
Supabase の設定が完了したので、対応する認証情報で Social Login プラグインをセットアップする必要があります。 重要: プラグインには、OAuth 認証情報が必要です。 元のプロバイダー (Supabase経由ではなく)、Supabaseはサーバー側の認証を処理します。
認証フローの仕組み
設定に入る前に、フローを理解しておきましょう:
- プラグインが認証を実行 ソーシャルプロバイダー(Google/Apple/Facebook)とネイティブで連携
- プラグインがトークンを受信 プロバイダーから(アクセストークン、IDトークン)を取得
- アプリがこれらのトークンを送信 Supabaseへ送信
signInWithIdToken() - Supabaseが検証 プロバイダーとトークンを照合し、ユーザーセッションを作成
- Supabaseが返却 アプリの認証リクエスト用の独自のJWTトークン
Googleプラグインの設定
プラグインには以下が必要です: WebクライアントID 全プラットフォーム用、および任意で iOS クライアント ID iOS固有の機能を使用する場合:
import { SocialLogin } from '@capgo/capacitor-social-login';
await SocialLogin.initialize({
google: {
// Use the same Web Client ID you configured in Supabase
webClientId: 'YOUR_WEB_CLIENT_ID.apps.googleusercontent.com',
// Optional: iOS Client ID for iOS-specific features
iOSClientId: 'YOUR_IOS_CLIENT_ID.apps.googleusercontent.com',
// Use online mode so the plugin returns an idToken for Supabase
mode: 'online'
}
});
Google設定の重要ポイント:
- 以下の WebクライアントID (Android/iOSのクライアントIDではなく) 対象の
webClientIdフィールド用 - Web Client ID さえあれば、全プラットフォームで動作します
- この
iOSClientIdは任意で、iOS固有のGoogle機能を使用する場合のみ必要です
Apple プラグインの設定
Apple の設定は iOS と Android で異なります:
iOS向け (ネイティブの Apple Sign-In):
await SocialLogin.initialize({
apple: {
// No additional configuration needed for iOS
// The plugin uses the native Apple Sign-In capability
}
});
Android/Web の場合 (Service ID が必要)。以下のリダイレクトルールを buildApplePluginConfig() React のチュートリアルと同様に使用してください:
import { Capacitor } from '@capacitor/core';
const platform = Capacitor.getPlatform();
await SocialLogin.initialize({
apple:
platform === 'android'
? {
clientId: 'YOUR_SERVICE_ID',
redirectUrl:
'https://your-project-ref.supabase.co/functions/v1/apple-signin-callback',
}
: {
clientId: 'YOUR_SERVICE_ID',
redirectUrl: window.location.href,
},
});
Apple 設定の重要ポイント:
- iOS はネイティブの Sign in with Apple を使用します(追加設定は不要)
- Androidでは、Service IDとSupabaseの
apple-signin-callbackEdge Function URLを使用します - Webでは、Service IDと
window.location.href、これはAppleのReturn URLと一致させる必要があります
Facebook Pluginの設定
Facebookでは、App IDとClient Tokenが必要です:
await SocialLogin.initialize({
facebook: {
appId: 'YOUR_FACEBOOK_APP_ID', // From Facebook Developer Dashboard
clientToken: 'YOUR_FACEBOOK_CLIENT_TOKEN', // From Facebook Developer Dashboard
// Optional: Use Facebook Limited Login (for enhanced privacy)
limitedLogin: false // See our Facebook setup guide for important Limited Login details
}
});
Facebookに関する重要事項:
- Supabaseで設定したものと同じApp IDを使用してください
- Client TokenはFacebook AppのBasic Settingsにあります
limitedLogin: trueFacebookのプライバシー重視のLimited Login機能を有効化(iOSのみ)- 重要:詳細は当社の Facebookの設定ガイド ATTに関する考慮事項を含む、詳細なLimited Loginの情報については

プラグインの初期化を完了する
すべてのプロバイダーをまとめて初期化する方法は以下の通りです:
import { SocialLogin } from '@capgo/capacitor-social-login';
export async function initializeSocialLogin() {
await SocialLogin.initialize({
google: {
webClientId: 'YOUR_WEB_CLIENT_ID.apps.googleusercontent.com',
mode: 'online'
},
facebook: {
appId: 'YOUR_FACEBOOK_APP_ID',
clientToken: 'YOUR_FACEBOOK_CLIENT_TOKEN',
},
apple: {
// Prefer buildApplePluginConfig() from the React walkthrough.
// Android: redirectUrl = Supabase apple-signin-callback Edge Function
// Web: redirectUrl = window.location.href
}
});
}
重要な注意点:
- 呼び出す
initialize()一度だけ ログインのたびではなく、アプリの起動時に - 使用する予定のプロバイダーのみを設定すればOKです
- ここでの認証情報は以下から取得しています 元のプロバイダーSupabaseからではなく、
- プロバイダーの認証情報がSupabaseの設定と一致していることを確認してください
ReactのSupabaseクライアントと認証レイヤー
まだSupabaseクライアントをインストールしていない場合は、以下を実行してください:
bun add @supabase/supabase-js
Reactツリー全体で共有する単一のクライアントを作成します:
// src/lib/supabaseClient.ts
import { createClient } from '@supabase/supabase-js';
const supabaseUrl = import.meta.env.VITE_SUPABASE_URL;
const supabaseAnonKey = import.meta.env.VITE_SUPABASE_ANON_KEY;
export const supabase = createClient(supabaseUrl, supabaseAnonKey, {
auth: {
autoRefreshToken: true,
persistSession: true,
detectSessionInUrl: false,
},
});
Google + Supabase用のNonceヘルパー
Supabaseが要求するのは、 生のnonce における signInWithIdToken と、 SHA-256ダイジェスト をGoogleに渡すことです。 Supabase Google連携ガイド 一連の流れをドキュメント化しています。最小限のヘルパー:
// src/auth/nonce.ts
export function getUrlSafeNonce(): string {
const array = new Uint8Array(32);
crypto.getRandomValues(array);
return Array.from(array, (byte) => byte.toString(16).padStart(2, '0')).join('');
}
export async function sha256Hex(message: string): Promise<string> {
const data = new TextEncoder().encode(message);
const hashBuffer = await crypto.subtle.digest('SHA-256', data);
return Array.from(new Uint8Array(hashBuffer), (b) => b.toString(16).padStart(2, '0')).join('');
}
export async function createGoogleNoncePair(): Promise<{ rawNonce: string; nonceDigest: string }> {
const rawNonce = getUrlSafeNonce();
const nonceDigest = await sha256Hex(rawNonce);
return { rawNonce, nonceDigest };
}
Social LoginとSupabaseを一つのモジュールに統合(〜のパターンを使用) 例 supabaseAuthUtils.ts):
// src/auth/socialLogin.ts
import { Capacitor } from '@capacitor/core';
import { SocialLogin } from '@capgo/capacitor-social-login';
import { supabase } from '../lib/supabaseClient';
import { createGoogleNoncePair } from './nonce';
export function isAppleLoginConfigured(): boolean {
const platform = Capacitor.getPlatform();
if (platform === 'ios') return true;
const serviceId = import.meta.env.VITE_APPLE_SERVICE_ID;
if (!serviceId) return false;
if (platform === 'android') {
return Boolean(import.meta.env.VITE_SUPABASE_APPLE_CALLBACK_URL);
}
if (platform === 'web') return true;
return false;
}
function buildApplePluginConfig() {
const platform = Capacitor.getPlatform();
if (platform === 'ios') {
return {};
}
if (platform === 'android') {
return {
clientId: import.meta.env.VITE_APPLE_SERVICE_ID,
redirectUrl: import.meta.env.VITE_SUPABASE_APPLE_CALLBACK_URL,
};
}
if (platform === 'web') {
return {
clientId: import.meta.env.VITE_APPLE_SERVICE_ID,
redirectUrl: window.location.href,
};
}
return {};
}
function isGoogleNonceMismatch(error: { message?: string }): boolean {
return (error.message ?? '').toLowerCase().includes('nonce');
}
let initialization: Promise<void> | null = null;
export function ensureSocialLoginInitialized(): Promise<void> {
if (!initialization) {
const initOptions: Parameters<typeof SocialLogin.initialize>[0] = {
google: {
webClientId: import.meta.env.VITE_GOOGLE_WEB_CLIENT_ID,
iOSClientId: import.meta.env.VITE_GOOGLE_IOS_CLIENT_ID,
mode: 'online',
},
};
if (isAppleLoginConfigured()) {
initOptions.apple = buildApplePluginConfig();
}
initialization = SocialLogin.initialize(initOptions).catch((error) => {
initialization = null;
throw error;
});
}
return initialization;
}
async function signInWithGoogleSupabaseOnce(allowNonceRetry: boolean) {
await ensureSocialLoginInitialized();
const { rawNonce, nonceDigest } = await createGoogleNoncePair();
const result = await SocialLogin.login({
provider: 'google',
options: {
scopes: ['email', 'profile'],
nonce: nonceDigest,
},
});
const googleResult = result.result;
if (!googleResult || googleResult.responseType !== 'online' || !googleResult.idToken) {
throw new Error('Google login did not return an ID token');
}
const { data, error } = await supabase.auth.signInWithIdToken({
provider: 'google',
token: googleResult.idToken,
nonce: rawNonce,
});
if (error) {
if (allowNonceRetry && isGoogleNonceMismatch(error)) {
await SocialLogin.logout({ provider: 'google' });
return signInWithGoogleSupabaseOnce(false);
}
throw error;
}
return data;
}
export async function signInWithGoogleSupabase() {
return signInWithGoogleSupabaseOnce(true);
}
export async function signInWithAppleSupabase() {
if (!isAppleLoginConfigured()) {
throw new Error('Apple sign-in is not configured for this platform');
}
await ensureSocialLoginInitialized();
const result = await SocialLogin.login({
provider: 'apple',
options: { scopes: ['email', 'name'] },
});
const appleIdToken = result.result?.idToken;
if (!appleIdToken) throw new Error('Apple login did not return an idToken');
const { data, error } = await supabase.auth.signInWithIdToken({
provider: 'apple',
token: appleIdToken,
});
if (error) throw error;
return data;
}
export async function signOutEverywhere() {
await supabase.auth.signOut();
await Promise.all([
SocialLogin.logout({ provider: 'google' }),
SocialLogin.logout({ provider: 'apple' }),
]);
}
Apple initialize プラットフォーム別 ( Supabase Apple 共通, Android, Web):
- iOSと:
buildApplePluginConfig()を返します{}. Native Sign in with Apple では、bundle ID を使用します。NoredirectUrl. - Android:
clientIdが Apple Service ID です。redirectUrlは Supabase Edge Function (apple-signin-callback) です。関数をデプロイし、Apple Return URL にそのエンドポイントを設定し、アプリのディープリンク intent filter を追加して、フローが WebView に戻れるようにしてください (Android Supabase Apple ガイド). - Web:
clientIdが Service ID です。redirectUrlがwindow.location.href、これは Apple Developer Portal の Return URL と一致している必要があります (Web Supabase Apple ガイド).
ensureSocialLoginInitialized() 以下を追加します: apple providerのみを指定する場合 isAppleLoginConfigured() がtrueの場合のみです。そのため、Googleのみの設定では、AndroidやWeb用の空のApple認証情報が渡されることはありません。
プラグインが返す値は result.idToken すべてのプラットフォームで共通です(AppleProviderResponse における @capgo/capacitor-social-login)。複数のプラットフォームでリリースする場合は、SupabaseにiOSのApp IDとService IDの両方を登録してください。
コンポーネントにセッション状態を公開:
// src/auth/useAuth.tsx
import {
createContext,
useCallback,
useContext,
useEffect,
useMemo,
useState,
type ReactNode,
} from 'react';
import type { Session } from '@supabase/supabase-js';
import { supabase } from '../lib/supabaseClient';
import { ensureSocialLoginInitialized } from './socialLogin';
type AuthContextValue = {
session: Session | null;
loading: boolean;
initError: string | null;
clearInitError: () => void;
};
const AuthContext = createContext<AuthContextValue | null>(null);
export function AuthProvider({ children }: { children: ReactNode }) {
const [session, setSession] = useState<Session | null>(null);
const [loading, setLoading] = useState(true);
const [initError, setInitError] = useState<string | null>(null);
useEffect(() => {
void ensureSocialLoginInitialized()
.then(() => setInitError(null))
.catch((error) => {
setInitError(error instanceof Error ? error.message : 'Social login failed to initialize');
});
supabase.auth.getSession().then(({ data }) => {
setSession(data.session);
setLoading(false);
});
const { data: subscription } = supabase.auth.onAuthStateChange((_event, nextSession) => {
setSession(nextSession);
});
return () => subscription.subscription.unsubscribe();
}, []);
const clearInitError = useCallback(() => setInitError(null), []);
const value = useMemo(
() => ({ session, loading, initError, clearInitError }),
[session, loading, initError, clearInitError],
);
return <AuthContext.Provider value={value}>{children}</AuthContext.Provider>;
}
export function useAuth() {
const ctx = useContext(AuthContext);
if (!ctx) throw new Error('useAuth must be used inside AuthProvider');
return ctx;
}
ReactのログインUIと保護されたルート

ログインパネル:
// src/components/LoginPanel.tsx
import { useState } from 'react';
import {
isAppleLoginConfigured,
signInWithAppleSupabase,
signInWithGoogleSupabase,
} from '../auth/socialLogin';
import { useAuth } from '../auth/useAuth';
export function LoginPanel() {
const { initError, clearInitError } = useAuth();
const [error, setError] = useState<string | null>(null);
const [busy, setBusy] = useState(false);
const showApple = isAppleLoginConfigured();
const run = async (action: () => Promise<unknown>) => {
setBusy(true);
setError(null);
try {
await action();
clearInitError();
} catch (e) {
setError(e instanceof Error ? e.message : 'Sign-in failed');
} finally {
setBusy(false);
}
};
return (
<div>
<button type="button" disabled={busy} onClick={() => run(signInWithGoogleSupabase)}>
Continue with Google
</button>
{showApple ? (
<button type="button" disabled={busy} onClick={() => run(signInWithAppleSupabase)}>
Continue with Apple
</button>
) : null}
{initError ? <p role="alert">{initError}</p> : null}
{error ? <p role="alert">{error}</p> : null}
</div>
);
}
セッションのデバッグビュー(後で実際のユーザー用UIに置き換えてください):
// src/components/SessionDebug.tsx
import { useEffect, useState } from 'react';
import type { User } from '@supabase/supabase-js';
import { supabase } from '../lib/supabaseClient';
import { signOutEverywhere } from '../auth/socialLogin';
export function SessionDebug() {
const [user, setUser] = useState<User | null>(null);
useEffect(() => {
supabase.auth.getUser().then(({ data }) => setUser(data.user));
}, []);
return (
<div>
<button type="button" onClick={() => signOutEverywhere()}>Sign out</button>
<pre>{JSON.stringify(user, null, 2)}</pre>
</div>
);
}

〜を使ったルート react-router-dom:
// src/App.tsx
import { BrowserRouter, Navigate, Route, Routes } from 'react-router-dom';
import { AuthProvider, useAuth } from './auth/useAuth';
import { LoginPanel } from './components/LoginPanel';
import { SessionDebug } from './components/SessionDebug';
function HomePage() {
const { session, loading } = useAuth();
if (loading) return <p>Loading…</p>;
if (session) return <Navigate to="/account" replace />;
return <LoginPanel />;
}
function AccountPage() {
const { session, loading } = useAuth();
if (loading) return <p>Loading…</p>;
if (!session) return <Navigate to="/" replace />;
return <SessionDebug />;
}
export default function App() {
return (
<AuthProvider>
<BrowserRouter>
<Routes>
<Route path="/" element={<HomePage />} />
<Route path="/account" element={<AccountPage />} />
</Routes>
</BrowserRouter>
</AuthProvider>
);
}
アプリを〜にマウント main.tsx 通常どおり。プロバイダーへのログイン成功後、 onAuthStateChange アップデート session そして React Router がユーザーを〜へ遷移させます /account.
オプション: Facebook
Facebook も同様の signInWithIdToken プラグインのアクセストークンを使う同じパターンです。参照: Facebook のセットアップ および〜のプロバイダーブロック ステップ 4.
ReactアプリにCapacitorを追加する
Web bundleをビルドし、次にネイティブプロジェクトを追加します:
bun run build
bun add @capacitor/core @capacitor/cli @capacitor/ios @capacitor/android
bunx cap init "Capgo Auth Demo" com.example.authdemo --web-dir dist
bunx cap add ios
bunx cap add android

Webビルドのたびに同期を実行:
bun run build
bunx cap sync
実機テストの準備ができたら、ネイティブIDEを開きます:
bunx cap open ios
bunx cap open android
実機でテストする前に、GoogleとAppleのプラットフォーム設定を完了させてください:
ディープリンクとUniversal Links
WebView内で呼び出す supabase.auth.signInWithOAuth チュートリアルには、多くの場合 Universal Links が必要です または App Links Googleによるリダイレクト後、OSがアプリに制御を戻します。Native Google によるサインインは、 IDトークン を使用することで、プラグインがブラウザでのOAuthラウンドトリップを行わないため、リダイレクトループを回避できます。 AndroidでのAppleログインは、 仕組みが異なります。Edge Functionのリダイレクトと、アプリの ディープリンク およびintent filterを使用するため、Appleログイン後にWebViewを再開できます。
他の機能(パスワードリセットメール、マジックリンク、マーケティング用URLなど)のためにdeep linkを設定する場合もあります。同じパスを以下に追加してください: 認証 > URL設定 Supabaseおよび apple-app-site-association / Androidのintent filterに、これらのフローを追加する際に設定します。
ステップ 8: プラットフォーム別の設定
iOSの設定
iOSの詳細なセットアップ手順については、以下のプラットフォーム別ガイドを参照してください:
- Google iOS セットアップ - URLスキーム、Info.plistの設定
- Apple iOS セットアップ - Sign in with Apple の機能設定
- Facebook iOS セットアップ (一般的なFacebookガイド内) - Facebook SDK の設定
クイックサマリー - 追加先 ios/App/App/Info.plist:
<!-- Google Sign-In URL scheme -->
<key>CFBundleURLTypes</key>
<array>
<dict>
<key>CFBundleURLSchemes</key>
<array>
<string>YOUR_REVERSED_CLIENT_ID</string>
</array>
</dict>
</array>
<!-- Apple Sign-In capability -->
<key>com.apple.developer.applesignin</key>
<array>
<string>Default</string>
</array>
Xcodeプロジェクトの設定を含む、iOSの完全なセットアップ手順については、リンク先のガイドに従ってください。
Androidの設定
Androidの詳細なセットアップ手順については、以下のプラットフォーム別ガイドを参照してください:
- Google Android セットアップ - SHA-1フィンガープリント、Google Play Servicesの設定
- Apple Android セットアップ - Android用のService ID設定
- Facebook Android セットアップ (一般的なFacebookガイド内) - Facebook SDK 連携
必須の Android セットアップ:
1. SHA-1 フィンガープリントを取得 (Google の場合は必須):
# For debug builds (development)
cd android
./gradlew signingReport
# Look for the SHA1 fingerprint under "Variant: debug"
# Add this SHA1 to your Google Cloud Console Android OAuth client
2. AndroidManifest.xml の設定 - 以下を追加: android/app/src/main/AndroidManifest.xml:
<!-- Internet permission -->
<uses-permission android:name="android.permission.INTERNET" />
<!-- Facebook configuration -->
<meta-data
android:name="com.facebook.sdk.ApplicationId"
android:value="@string/facebook_app_id"/>
<meta-data
android:name="com.facebook.sdk.ClientToken"
android:value="@string/facebook_client_token"/>
3. Facebook リソースの追加 まで android/app/src/main/res/values/strings.xml:
<string name="facebook_app_id">YOUR_FACEBOOK_APP_ID</string>
<string name="facebook_client_token">YOUR_FACEBOOK_CLIENT_TOKEN</string>
Google Play Services の設定やパッケージ名の構成を含む、Android の完全な設定については、リンク先のプラットフォームガイドに従ってください。
ステップ 9: 認証済みユーザーによる Supabase データベースの利用
ユーザーが認証されると、Row Level Security (RLS) を適用した Supabase データベースを利用できます。
// Example: Fetch user profile
async function getUserProfile() {
const { data: user } = await supabase.auth.getUser();
if (user) {
const { data, error } = await supabase
.from('profiles')
.select('*')
.eq('id', user.user.id)
.single();
return data;
}
}
// Example: Update user profile
async function updateUserProfile(updates: any) {
const { data: user } = await supabase.auth.getUser();
if (user) {
const { data, error } = await supabase
.from('profiles')
.update(updates)
.eq('id', user.user.id);
return data;
}
}
重要なセキュリティ上の考慮事項
- 機密性の高いキーを公開しない クライアント側の code に含めない
- 環境変数を利用する 設定管理には環境変数を使用
- Row Level Security を有効にする Supabase の RLS を設定
- トークンの検証を行う 必要に応じてバックエンドで検証
- トークンのリフレッシュ処理 Supabase で自動的にリフレッシュ
既知の問題とトラブルシューティング
Google での Nonce 不一致 (特に iOS)
Supabaseでnonceエラーが返る場合、GoogleがキャッシュされたIDトークンを返している可能性があります。プラグイン経由でGoogleからログアウトし、1回だけ再試行して、渡していることを確認してください nonceDigest まで SocialLogin.login と rawNonce まで signInWithIdToken。 サンプルアプリ 〜後の再試行 SocialLogin.logout.
トークンのaudienceエラー
すべてのGoogleクライアントID(web、iOS、Android)をSupabaseのGoogleプロバイダーに登録してください。 aud IDトークン内のclaimは、そのいずれかと一致している必要があります。
OAuthリダイレクトのチュートリアルとこのガイドの比較
〜を使っているブログ記事 signInWithOAuth WebViewでのリダイレクトがアプリではなくSafariで開いてしまうと、モバイルでは失敗することがあります。ネイティブログイン、または signInWithIdToken Capacitorにはこちらを、あるいは Social LoginのWebセットアップを ブラウザのリダイレクトに利用してください。
プラットフォーム別の確認事項
- iOS: bundle IDとURL schemesの設定( Google iOSセットアップより)
- Android: SHA-1フィンガープリントの設定( Google Androidセットアップより)
- 詳細は プラグインのトラブルシューティング まとめて解決策を確認する
トークンの不一致とネットワークエラー
- Google Cloud、Supabase、および
SocialLogin.initialize - Reactでのローディングとエラー状態の表示(上記
LoginPanelを参照)
まとめ
これで、Supabaseの堅牢なバックエンドとネイティブなソーシャルログインを組み合わせた、完全な認証システムが整いました。この構成により、以下が可能になります:
- 安全なネイティブ・ソーシャル認証
- シームレスなトークン管理
- リアルタイムなデータベース連携
- クロスプラットフォーム対応
SupabaseとCapgo Social Loginプラグインを組み合わせることで、Capacitorアプリに強力でスケーラブルな認証ソリューションを提供できます。
次のような高度な機能については: 多要素認証(MFA)を または カスタムクレーム、以下を確認してください: Supabase ドキュメント および Social Login プラグインのドキュメント.
Capacitor Social Login プラグインを使用した Supabase Authentication のセットアップから先に進む
使用している場合 Capacitor Social Login プラグインを使用した Supabase Authentication のセットアップ 認証とアカウントフローを計画するには、これを次と連携させてください @capgo/capacitor-social-login @capgo/capacitor-social-login の実装の詳細については、 @capgo/capacitor-passkey @capgo/capacitor-passkey の実装詳細については、 @capgo/capacitor-native-biometric @capgo/capacitor-native-biometric の実装の詳細については、 2要素認証 二要素認証の実装の詳細については、また、 SSO (エンタープライズ) SSO (Enterprise) の実装の詳細については。