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

AI を使って Auth0 を統合する

Claude Code、Cursor、GitHub Copilot などの AI コーディングアシスタントを使用している場合は、agent skills を使って数分で Auth0 認証を自動的に追加できます。まず、Auth0 agent skills をインストールします。
npx skills add auth0/agent-skills --skill auth0-quickstart --skill auth0-ionic-react
次に、AI アシスタントに次のように依頼します。
Add Auth0 authentication to my Ionic React app
AI アシスタントは、Auth0 アプリケーションの作成、認証情報の取得、Auth0 React SDK と Capacitor プラグインのインストール、ディープリンクの設定、ネイティブブラウザー統合によるログイン/ログアウト フローの実装を自動的に行います。詳しくは、Auth0 agent skills を参照してください。

はじめに

このクイックスタートでは、Capacitor を使用した Ionic React アプリケーションに Auth0 の認証を追加する方法を説明します。Auth0 React SDK と Capacitor のネイティブブラウザー統合を使用して、ログイン、ログアウト、ユーザープロフィール機能を備えたモバイル対応アプリを構築します。
1

新しいプロジェクトを作成

Capacitor を使用して新しい Ionic React アプリを作成する
npx ionic start auth0-ionic-react tabs --type=react --capacitor
プロジェクトを開く
cd auth0-ionic-react
@ionic/cli パッケージを使用していることを確認してください (非推奨の ionic パッケージではありません) 。プロジェクトの作成時に --npm-client に関するエラーが表示される場合は、CLI を更新してください。
npm uninstall -g ionic
npm i -g @ionic/cli
すでに Ionic React アプリがある場合は、Capacitor が有効になっていることを確認してください。ionic integrations enable capacitor を実行し、続けて npx cap init を実行すると追加できます。
2

Auth0 React SDK と Capacitor プラグインをインストールする

Ionic のスターターtemplateでは react@19.0.0 が生成されることがありますが、これは Auth0 React SDK と互換性がありません。まず、サポート対象の React バージョンを使用していることを確認してください。
npm install react@^19.0.1 react-dom@^19.0.1
次に、Auth0 SDK と Capacitor プラグインをインストールします。
npm install @auth0/auth0-react @capacitor/browser @capacitor/app && npx cap sync
iOS の Capacitor Browser プラグインは SFSafariViewController を使用しますが、iOS 11 以降ではデバイス上の Safari と cookie を共有しません。そのため、これらのデバイスでは SSO は機能しません。SSO が必要な場合は、ASWebAuthenticationSession を使用する互換性のあるプラグインを使用してください。
3

Auth0アプリを設定する

次に、Auth0テナントで新しいアプリを作成し、プロジェクトに環境変数を追加します。Auth0アプリのセットアップ方法は3つあります。Quick Setupツールを使用する (推奨) 、CLIコマンドを実行する、またはDashboardから手動で設定する方法から選択してください。
この quickstart 全体では、YOUR_PACKAGE_ID はアプリケーションのパッケージ ID を表します。これは capacitor.config.ts ファイル内の appId フィールドです (例: io.ionic.starter) 。詳しくは、Capacitor の Config スキーマ を参照してください。
Auth0 アプリを作成し、適切な設定値があらかじめ入力された .env ファイルをコピーします。アプリを作成したら、Auth0 DashboardSettings に移動し、Allowed Callback URLsAllowed Logout URLs を更新して、YOUR_PACKAGE_ID を実際のパッケージ ID に、YOUR_AUTH0_DOMAIN を Auth0 ドメインに置き換えます。
YOUR_PACKAGE_ID://YOUR_AUTH0_DOMAIN/capacitor/YOUR_PACKAGE_ID/callback
また、Application TypeNative に、Token Endpoint Authentication MethodNone に設定されていることを確認してください。
.env ファイルが存在することを確認してください: cat .env (Mac/Linux) または type .env (Windows)
4

Auth0Provider を設定する

src/main.tsx を開き、App コンポーネントを Auth0Provider でラップします。useRefreshTokensuseRefreshTokensFallback はモバイル向けの設定であり、iOS および Android 上の Ionic アプリでは必須です。
src/main.tsx
import React from 'react';
import { createRoot } from 'react-dom/client';
import App from './App';
import { Auth0Provider } from '@auth0/auth0-react';

// capacitor.config.ts の appId と一致させる必要があります
const appId = 'io.ionic.starter';

createRoot(document.getElementById('root')!).render(
  <React.StrictMode>
    <Auth0Provider
      domain={import.meta.env.VITE_AUTH0_DOMAIN}
      clientId={import.meta.env.VITE_AUTH0_CLIENT_ID}
      useRefreshTokens={true}
      useRefreshTokensFallback={false}
      authorizationParams={{
        redirect_uri: `${appId}://${import.meta.env.VITE_AUTH0_DOMAIN}/capacitor/${appId}/callback`
      }}
    >
      <App />
    </Auth0Provider>
  </React.StrictMode>
);
  • useRefreshTokens: Ionic を Android または iOS で使用する場合は必須です。モバイルブラウザーではサードパーティ Cookie がブロックされるため、SDK は iframe ベースのサイレント認証ではなくリフレッシュトークンを使用します。
  • useRefreshTokensFallback: モバイルでは利用できない iframe ベースのサイレント認証を SDK が試行しないよう、false に設定する必要があります。
  • authorizationParams.redirect_uri: OS が Auth0 コールバックをアプリに戻せるように、パッケージ ID をカスタム URL スキームとして使用します。
アプリケーションを閉じて再度開いたあとも認証状態を維持するには、cacheLocationlocalstorage に設定することを検討できますが、localstorage にトークンを保存するリスクに注意してください。Capacitor では、localstorage は一時的なものとして扱う必要があります。OS によって予期せず消去される可能性があります。Capacitor のストレージに関するガイダンスを参照してください。トークンの保存に Capacitor の Preferences plugin を使用することは推奨しません。これは UserDefaults (iOS) および SharedPreferences (Android) を基盤としており、暗号化されておらず、クラウドに同期される可能性があるためです。より安全で永続的なストレージメカニズムが必要な場合、SDK はカスタムキャッシュ実装をサポートしています。
5

ログイン、ログアウト、ユーザープロファイル、コールバックハンドラーを作成する

ファイルを作成する
touch src/LoginButton.tsx && touch src/LogoutButton.tsx && touch src/Profile.tsx
次のコードスニペットを追加してくださいLoginButton および LogoutButtonopenUrl コールバックは、Capacitor の Browser プラグインを使用して、アプリを完全に離れることなく、デバイスのシステムブラウザコンポーネントで Auth0 のログインページおよびログアウトページを開きます。App コンポーネントは appUrlOpen イベントをリッスンします。このイベントは、Auth0 がカスタム URL スキームを使用してアプリにリダイレクトバックする際に発火します。handleRedirectCallback を呼び出して認可コードをトークンと交換し、その後ブラウザを閉じます。
デフォルトでは、SDK の loginWithRedirect メソッドは window.location.href を使用してログインページに移動するため、デバイスのデフォルトのブラウザーアプリが開きます。openUrlBrowser.open を使用するように設定すると、認証フローをアプリ内のコンテキストに維持できるため、ユーザーエクスペリエンスが向上します。
6

アプリを実行する

まずはブラウザーでテストする
ionic serve
ブラウザーで ionic serve を実行する場合、ブラウザーはカスタム URL スキームを処理できないため、カスタム URL スキームのリダイレクト (io.ionic.starter://...) は機能しません。ブラウザーでテストするには、src/main.tsxredirect_uri を一時的に http://localhost:8100 に変更し、Dashboard の Auth0 アプリの Allowed Callback URLsAllowed Logout URLshttp://localhost:8100 を追加してください。ネイティブ向けにビルドする前に、この変更を元に戻すことを忘れないでください。
デバイスまたはシミュレーターで実行するには、まずネイティブプラットフォームを追加します。
npx cap add ios
npx cap add android
次に、ビルド、同期、実行を行います。
ionic build && npx cap sync && npx cap run ios
実行する前に、npx cap add を使用してネイティブプラットフォームを追加する必要があります。これはプラットフォームごとに一度だけ実行すれば十分です。その後、npx cap sync によって、ビルドした Web アセットがコピーされ、ネイティブプラグインが更新されます。
チェックポイントこれで、Ionic アプリで Auth0 ログインが完全に動作するようになっているはずです。デバイス上で実行している場合は、「ログイン」をタップするとシステムブラウザーで Auth0 の Universal Login ページが開き、認証後にアプリへリダイレクトされて、ユーザープロファイルが表示されます。

高度な使い方

デバイス上で Auth0 の callback を機能させるには、各プラットフォームでパッケージ ID をカスタム URL スキームとして登録します。iOSios/App/App/Info.plist に追加します。
ios/App/App/Info.plist
<key>CFBundleURLTypes</key>
<array>
  <dict>
    <key>CFBundleURLSchemes</key>
    <array>
      <string>io.ionic.starter</string>
    </array>
  </dict>
</array>
Androidandroid/app/src/main/AndroidManifest.xml のメイン <activity> 内に intent filter を追加します。
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="io.ionic.starter" />
</intent-filter>
io.ionic.starter は、capacitor.config.ts の実際の appId に置き換えてください。
詳細については、iOS の場合は Defining a Custom URL Scheme、Android の場合は Create Deep Links to App Content を参照してください。
Auth0 の認証状態を使用して、Ionic アプリケーション内の特定のルートを保護します。
src/App.tsx
import { useAuth0, withAuthenticationRequired } from '@auth0/auth0-react';
import { IonReactRouter } from '@ionic/react-router';
import { IonRouterOutlet } from '@ionic/react';
import { Route, Redirect } from 'react-router-dom';
import HomePage from './pages/Home';
import DashboardPage from './pages/Dashboard';

const ProtectedRoute = ({ component, ...args }: any) => {
  const Component = withAuthenticationRequired(component, {
    onRedirecting: () => <div className="ion-padding">Loading...</div>,
  });
  return <Route {...args} render={() => <Component />} />;
};

const App: React.FC = () => {
  // ... 前の手順の callback handler

  return (
    <IonApp>
      <IonReactRouter>
        <IonRouterOutlet>
          <Route exact path="/home" component={HomePage} />
          <ProtectedRoute exact path="/dashboard" component={DashboardPage} />
          <Route exact path="/">
            <Redirect to="/home" />
          </Route>
        </IonRouterOutlet>
      </IonReactRouter>
    </IonApp>
  );
};
withAuthenticationRequired HOC は、未認証のユーザーが保護されたルートにアクセスしようとすると、自動的に Auth0 のログインページへリダイレクトします。
Auth0Provider を設定して API のオーディエンスを指定し、getAccessTokenSilently メソッドを使用してバックエンド用のアクセストークンを取得します。
src/main.tsx
<Auth0Provider
  domain={import.meta.env.VITE_AUTH0_DOMAIN}
  clientId={import.meta.env.VITE_AUTH0_CLIENT_ID}
  useRefreshTokens={true}
  useRefreshTokensFallback={false}
  authorizationParams={{
    redirect_uri: `${appId}://${import.meta.env.VITE_AUTH0_DOMAIN}/capacitor/${appId}/callback`,
    audience: "YOUR_API_IDENTIFIER"
  }}
>
  <App />
</Auth0Provider>
次に、コンポーネントから認証済みの API 呼び出しを実行します。
src/ApiCall.tsx
import { useState } from 'react';
import { useAuth0 } from '@auth0/auth0-react';
import { IonButton, IonText } from '@ionic/react';

const ApiCall: React.FC = () => {
  const { getAccessTokenSilently } = useAuth0();
  const [result, setResult] = useState<string | null>(null);

  const callApi = async () => {
    try {
      const token = await getAccessTokenSilently();

      const response = await fetch('https://your-api.example.com/protected', {
        headers: {
          Authorization: `Bearer ${token}`
        }
      });

      const data = await response.json();
      setResult(JSON.stringify(data, null, 2));
    } catch (error) {
      console.error('API call failed:', error);
    }
  };

  return (
    <div className="ion-padding">
      <IonButton onClick={callApi}>Call Protected API</IonButton>
      {result && (
        <IonText>
          <pre>{result}</pre>
        </IonText>
      )}
    </div>
  );
};

export default ApiCall;