メインコンテンツへスキップ

Capacitor で Auth0 を使ってサインインする方法

OIDCとPKCEでCapacitor 8アプリにAuth0ログインを追加: Auth0ダッシュボードの設定、コールバックURL、API オーディエンス、リフレッシュトークン、ログアウト、トラブルシューティング。

Capacitor アプリからシステムブラウザ経由で開かれる Auth0 Universal Login

Capacitor アプリで Auth0 にサインインするには、 ネイティブ Auth0 でアプリケーションを作成し、次のようなカスタムスキームのコールバック URL を登録します: com.example.app://oauth/auth0その後、システムブラウザ経由で PKCE を使った OpenID Connect 認可 code フローを実行します。これで @capgo/capacitor-social-login 1 回の initialize Auth0 エンドポイントへの呼び出しと 1 回の SocialLogin.login({ provider: 'oauth2', options: { providerId: 'auth0' } }).

このガイドでは、Auth0 ダッシュボードの設定、iOS、Android、Web 向けのクライアント code、API アクセストークン、リフレッシュトークン、ログアウト、そして遭遇するエラーについて説明します。2026 年 10 月時点の Capacitor 8 向けに書かれています。

Capacitor における Auth0 フローの仕組み

Auth0 がログインページ(Universal Login)をホストします。アプリがパスワードを目にすることはありません。フローは次のとおりです:

  1. アプリはPKCEのverifierとchallengeを生成し、次に https://YOUR_TENANT/authorize をセキュアなブラウザで開きます。
  2. ユーザーがサインインします(パスワード、ソーシャル、passkey、MFAなど、Auth0で設定した方法)。
  3. Auth0は、使い捨ての code.
  4. アプリは code と PKCE バリデーターを交換します /oauth/token に交換して、IDトークン、アクセストークン、場合によってはリフレッシュトークンを取得します。

使用するブラウザはプラットフォームによって異なります:

プラットフォーム ブラウザ Callbackの処理
iOSと ASWebAuthenticationSession システムが処理するため、 Info.plist 変更
Androidでは デフォルトでは埋め込み WebView、または androidUseCustomTabs: true Custom Tabs には intent フィルタが必要です
Web ポップアップ(デフォルト)または全ページリダイレクト handleRedirectCallback() リターンページで

Android では Custom Tabs を使用してください。Chrome とクッキーを共有し、passkey やパスワードマネージャーに対応しており、Auth0 が期待する RFC 8252(ネイティブアプリ向け OAuth)に準拠しています。

ステップ 1: Auth0 アプリケーションの設定

  1. では Auth0 ダッシュボード、へ移動 Applications > Applications > Create Application.
  2. 選ぶ ネイティブ を作成します。
  3. 「 設定 タブで、次をメモしてください ドメイン (例: example.eu.auth0.com) と クライアントID.
  4. 未満 認証情報、認証方法が...であることを確認してください なし。これはPKCEで使用されるpublic-client設定です。

コールバックURLとログアウトURL

これらのフィールドを入力してください Settings > Application URIs:

項目 モバイル用 Web用
許可された Callback URL com.example.app://oauth/auth0 https://app.example.com/auth/callback
許可されたログアウトURL com.example.app://oauth/logout https://app.example.com/
許可された Web オリジン 不要 https://app.example.com

複数の値はカンマで区切ってください。スキームには Capacitor を使用します appId 。リバースドメイン形式のスキームは、他のアプリとの衝突を避けるのに適しています。Web ビルドも提供する場合は、多くのチームが Web 用に別の シングルページアプリケーション を Auth0 に作成し、Web とモバイルの設定が混在しないようにしています。

リフレッシュトークン

ユーザーがログイン状態を維持できるようにするには:

  1. では Settings > Refresh Token Rotationで、ローテーションをオンにします。各リフレッシュで新しいリフレッシュトークンが返され、古いものは無効化されます。
  2. プロダクトに合った絶対期限と非アクティブ期限を設定してください。
  3. 独自の API を呼び出す場合は、次を開き Applications > APIs > 対象の API > Settings を有効にします オフラインアクセスを許可.
  4. 次をリクエストします offline_access アプリ内のスコープ。

API の読者の皆様へ

バックエンドでAuth0のアクセストークンを検証する場合は、API を作成し、 アプリケーション > API たとえば次のような識別子を付けて、 https://api.example.com。その識別子を audienceとして渡します。これがないと、アクセストークンはAuth0の /userinfo エンドポイントでしか使えません。

ステップ 2: プラグインのインストールと設定

bun add @capgo/capacitor-social-login
bunx cap sync

Auth0だけを使う場合は、バイナリを小さく保つため、同梱のソーシャルSDKを無効にしてください:

// capacitor.config.ts
plugins: {
  SocialLogin: {
    providers: { google: false, facebook: false, apple: false, twitter: false },
  },
},

汎用のOAuth2エンジンはこれらのSDKに依存しません。

Custom Tabs用のAndroid intent filter

コールバックスキームを次に追加します: MainActivity における android/app/src/main/AndroidManifest.xml:

<intent-filter>
    <action android:name="android.intent.action.VIEW" />
    <category android:name="android.intent.category.DEFAULT" />
    <category android:name="android.intent.category.BROWSABLE" />
    <data android:scheme="com.example.app" android:host="oauth" />
</intent-filter>

Capacitor テンプレートには、すでに次が設定されています: android:launchMode="singleTask" で MainActivityこれはリダイレクトに必要です。そのまま残してください。

ステップ 3: Auth0 プロバイダーを初期化

import { Capacitor } from '@capacitor/core';
import { SocialLogin } from '@capgo/capacitor-social-login';

const AUTH0_DOMAIN = 'https://example.eu.auth0.com';
const isWeb = Capacitor.getPlatform() === 'web';

export async function initAuth() {
  await SocialLogin.initialize({
    oauth2: {
      auth0: {
        appId: 'YOUR_AUTH0_CLIENT_ID',
        authorizationBaseUrl: `${AUTH0_DOMAIN}/authorize`,
        accessTokenEndpoint: `${AUTH0_DOMAIN}/oauth/token`,
        resourceUrl: `${AUTH0_DOMAIN}/userinfo`,
        redirectUrl: isWeb
          ? 'https://app.example.com/auth/callback'
          : 'com.example.app://oauth/auth0',
        scope: 'openid profile email offline_access',
        pkceEnabled: true,
        additionalParameters: {
          audience: 'https://api.example.com',
        },
        logoutUrl: `${AUTH0_DOMAIN}/oidc/logout`,
        postLogoutRedirectUrl: isWeb
          ? 'https://app.example.com/'
          : 'com.example.app://oauth/logout',
        androidUseCustomTabs: true,
      },
    },
  });
}

明示的なエンドポイントは次に置き換えられます: issuerUrl: AUTH0_DOMAINその後、プラグインは次を読み取ります: /.well-known/openid-configuration明示的な値は自動検出された値より優先されます。これは Auth0 のカスタムドメインを使う場合に役立ちます。

Ionic Auth Connect から移行する場合、プラグインは次もエクスポートします: SocialLoginAuthConnect 次の auth0 プリセットで、次を受け取ります: domain, clientId, redirectUrl と audience。参照: Auth Connect移行ガイド.

ステップ 4: サインイン

import { SocialLogin } from '@capgo/capacitor-social-login';

export async function signInWithAuth0() {
  try {
    const { result } = await SocialLogin.login({
      provider: 'oauth2',
      options: { providerId: 'auth0' },
    });

    return {
      idToken: result.idToken,
      accessToken: result.accessToken?.token,
      expiresAt: result.accessToken?.expires,
      refreshToken: result.refreshToken,
      user: result.resourceData, // JSON from /userinfo
    };
  } catch (error: any) {
    if (error?.code === 'USER_CANCELLED') return null;
    throw error;
  }
}

便利なログインオプション:

  • prompt: 'login' Auth0にセッションCookieが残っていても、ログインページを強制表示します。
  • loginHint: 'user@example.com' メールアドレスを事前入力します。
  • additionalParameters: { connection: 'google-oauth2' } Universal Login をスキップし、特定の接続に直接移動します。
  • additionalParameters: { screen_hint: 'signup' } サインアップ画面を開きます。

Web リダイレクトコールバック

Web では、デフォルトのポップアップフローでは追加の処理は不要です。 flow: 'redirect'を使用する場合、コールバックページで結果を読み取ります:

const result = await SocialLogin.handleRedirectCallback();
if (result?.provider === 'oauth2') {
  console.log(result.result.idToken);
}

handleRedirectCallback は Web 専用で、iOS と Android では拒否されます。

ステップ 5: ID トークンを読み取り、API を呼び出す

ID トークンのデコードは、表示目的でクライアント側のみ行います:

const { claims } = await SocialLogin.decodeIdToken({ idToken: result.idToken! });
console.log(claims.email, claims.name, claims.sub);

decodeIdToken 署名は検証しません。セキュリティ関連の処理では、アクセストークンを API に送信して、そちらで検証してください:

import { createRemoteJWKSet, jwtVerify } from 'jose';

const jwks = createRemoteJWKSet(new URL('https://example.eu.auth0.com/.well-known/jwks.json'));

export async function verifyAuth0AccessToken(token: string) {
  const { payload } = await jwtVerify(token, jwks, {
    issuer: 'https://example.eu.auth0.com/', // Auth0 issuers end with a slash
    audience: 'https://api.example.com',
  });
  return payload; // payload.sub is the Auth0 user ID
}

ステップ 6: アクセストークンをリフレッシュする

import { SocialLogin } from '@capgo/capacitor-social-login';

export async function getValidAccessToken() {
  const { isLoggedIn } = await SocialLogin.isLoggedIn({ provider: 'oauth2', providerId: 'auth0' });

  if (!isLoggedIn) {
    // access token expired: try the stored refresh token
    try {
      await SocialLogin.refresh({ provider: 'oauth2', options: { providerId: 'auth0' } });
    } catch {
      // refresh token expired, revoked or already rotated: sign in again
      const loginResult = await signInWithAuth0();
      if (!loginResult) throw new Error('Sign-in cancelled');
    }
  }

  const { accessToken } = await SocialLogin.getAuthorizationCode({
    provider: 'oauth2',
    providerId: 'auth0',
  });
  return accessToken;
}

refresh リフレッシュトークンが期限切れまたは失効している場合は拒否されます。ローテーションが有効な場合、一度使用されたリフレッシュトークンも失敗するため、拒否時は必ずユーザーをサインイン画面に戻すよう処理してください。

refresh プラグインがログイン時に保存したリフレッシュトークンを使用します。リフレッシュトークンを自分で管理する場合、 SocialLogin.refreshToken({ provider: 'oauth2', providerId: 'auth0', refreshToken })、新しいトークンレスポンス全体を返します。ローテーションを有効にしている場合、新しいリフレッシュトークンを毎回保存してください。

プラグインはトークンのコピーをアプリ専用ストレージに保持します。セキュリティレビューで Keychain や Keystore が求められる場合は、リフレッシュトークンを以下で保存してください NativeBiometric.setData({ key, value }) と @capgo/capacitor-native-biometric 、それを渡します refreshToken ご自身で。私たちの セキュアなトークンストレージガイド がオプションを比較します。

ステップ 7: サインアウト

await SocialLogin.logout({ provider: 'oauth2', providerId: 'auth0' });

プラグインが保存済みトークンを削除し、次に logoutUrl を使用して id_token_hint と post_logout_redirect_uri を開くことで Auth0 がセッション Cookie をクリアします。Auth0 の /oidc/logout エンドポイントがこれらのパラメータを認識し、リダイレクト先は次に登録されている必要があります: 許可されたログアウトURL.

iOS と Android では、end-session ページがシステムブラウザで開くため、ユーザーは一時的にアプリを離れます。ローカルログアウトだけを行いたい場合は、省略し、 logoutUrl 渡します prompt: 'login' 次のサインイン時に、Auth0 のセッションが記憶されているためユーザーがそのままログインされないようにします。設定 iosPrefersEphemeralSession: true また、iOS での共有クッキーを回避できますが、アプリ間の SSO は利用できません。

トラブルシューティング

エラー 原因 解決策
Callback URL mismatch リダイレクト URL が許可されたコールバック URL にありません code の正確な値をダッシュボードにコピーし、スキームとホストを確認してください
Unauthorized または invalid_client で、シェアは /oauth/token アプリタイプが Native でない、または認証方法が None ではない Native として再作成し、トークンエンドポイントの認証を None に設定
いいえ refreshToken 結果内 offline_access 欠落しているか、API がオフラインアクセスを許可していません スコープを追加し、Allow Offline Access を有効化、ローテーションを有効化
アクセストークンを API で検証できません いいえ audience 送信済み 追加 audience における additionalParameters
Androidでログイン後にアプリが再オープンしない Intentフィルターのスキームまたはホストが一致しない redirectUrl 合わせる com.example.app と oauth 正確に
OAuth2 provider "auth0" not configured login 呼び出し前に initialize またはキーの不一致 Await initialize 起動時は同じものを使用してください providerId
ログアウトページが開いたままになります post_logout_redirect_uri Allowed Logout URLs に含まれていません 追加するか、ローカルのみのログアウトを使用してください
トークン交換時の Web CORS エラー Origin が Allowed Web Origins に含まれていません Web origin を追加するか、Web 用に SPA アプリケーションを使用してください

設定 logsEnabled: true プロバイダー設定に記述すると、デバッグ中に生成されたURLとトークン交換の詳細が出力されます。

ストアのリリースなしで認証の修正をデプロイ

スコープ、オーディエンス、エラー処理の変更は TypeScript のみです。 Capgo Live Updates その日のうちにユーザーへ修正を配信できます。新しいintent filterなどのネイティブ変更には新しいバイナリが必要ですが、 Capgo のビルド クラウド上で生成できます。

Capacitor アプリ向けの Live Updates

Web レイヤーのバグが本番で発生したら、App Store の審査を何日も待たずに Capgo で修正を配信しましょう。ネイティブの変更は通常の審査フローに残したまま、ユーザーはバックグラウンドでアップデートを受け取れます。

最新のブログ記事

Capgoは、真にプロフェッショナルなモバイルアプリを作るために必要な最高のインサイトを提供します。