メインコンテンツへスキップ
このクイックスタートは Expo アプリケーション向けです。React Native アプリケーションに Auth0 を統合する場合は、React Native クイックスタートを参照してください。

AI を使って Auth0 を統合する

Claude Code、Cursor、GitHub Copilot などの AI コーディングアシスタントを使用している場合は、agent skills を使って、数分で Auth0 認証を自動的に追加できます。インストール:
npx skills add auth0/agent-skills --skill auth0-quickstart --skill auth0-expo
次に、AI アシスタントに次のように依頼します:
Add Auth0 authentication to my Expo app
AI アシスタントが、Auth0 アプリケーションの作成、認証情報の取得、react-native-auth0 SDK のインストール、Expo プラグインの設定、ログイン / ログアウトフローの実装を自動的に行います。agent skills の詳細なドキュメント →

はじめに

1

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

このクイックスタート用に、新しい Expo プロジェクトを作成します。ターミナルで以下を実行します。
npx create-expo-app Auth0ExpoSample --template blank
cd Auth0ExpoSample
これにより、最新の SDK を使用した、ネイティブモジュールの統合に対応する最小構成の Expo アプリが作成されます。--template blank フラグを使用すると、余分なボイラープレートのないクリーンな開始点が得られます。
この SDK はカスタムネイティブコードを必要とするため、Expo Go には対応していません。開発ビルドを作成するには、npx expo run:ios または npx expo run:android を使用する必要があります。
2

Auth0 SDKをインストールする

Auth0 React Native SDK をプロジェクトに追加します。
npx expo install react-native-auth0
npx expo install を使用すると、Expo SDK のバージョンとの互換性を確保できます。SDK は Expo のプラグインシステムによって自動的に設定されます。
3

Expoプラグインを設定する

Auth0 プラグインを設定して、ネイティブ iOS および Android の構成を自動的に処理できるようにします。app.json を更新して、Auth0 プラグインを追加します。
app.json
{
  "expo": {
    "name": "Auth0ExpoSample",
    "slug": "auth0-expo-sample",
    "version": "1.0.0",
    "ios": {
      "bundleIdentifier": "com.auth0.samples.expo",
      "supportsTablet": true
    },
    "android": {
      "package": "com.auth0.samples.expo",
      "adaptiveIcon": {
        "foregroundImage": "./assets/images/adaptive-icon.png",
        "backgroundColor": "#ffffff"
      }
    },
    "plugins": [
      [
        "react-native-auth0",
        {
          "domain": "{yourDomain}",
          "customScheme": "auth0sample"
        }
      ]
    ]
  }
}
{yourDomain} をご利用の Auth0 ドメインに置き換えます (これは次の手順で取得します) 。
重要: app.json で、iOS の bundleIdentifier と Android の package を必ず定義してください。これらの識別子は、Auth0 SDK がネイティブプロジェクトを適切に設定するために必要です。カスタムスキームを指定しない場合、SDK は bundle identifier を URL スキームとして使用します。
customScheme には小文字のみを使用し、特殊文字は含めないでください。この値はコールバック URL の構築に使用され、authorize() メソッドと clearSession() メソッドに渡す必要があります。
4

Auth0アプリケーションを設定する

Expo アプリで使用できるように、Auth0 アプリケーションを作成して設定します。
  1. Auth0 Dashboard に移動します
  2. Applications > Applications > Create Application をクリックします
  3. ポップアップでアプリ名 (例: Auth0 Expo Sample) を入力し、アプリの種類として Native を選択して Create をクリックします
  4. Application Details ページで Settings タブを開きます
  5. ドメインクライアントID の値を控えます
  6. app.json のプラグイン設定にある domain の値を、Auth0 のドメインに更新します
Allowed Callback URLs:
auth0sample://{yourDomain}/ios/com.auth0.samples.expo/callback,
auth0sample://{yourDomain}/android/com.auth0.samples.expo/callback
許可するログアウト URL:
auth0sample://{yourDomain}/ios/com.auth0.samples.expo/callback,
auth0sample://{yourDomain}/android/com.auth0.samples.expo/callback
{yourDomain} を実際の Auth0 ドメイン (例: dev-abc123.us.auth0.com) に置き換えてください。
Allowed Callback URLs は、認証後にユーザーを安全にアプリケーションへ戻すための重要なセキュリティ対策です。一致する URL がない場合、ログイン処理は失敗し、ユーザーはアプリにアクセスできず、代わりに Auth0 のエラーページが表示されます。Allowed Logout URLs は、サインアウト時にシームレスなユーザー体験を提供するために不可欠です。一致する URL がない場合、ログアウト後にユーザーはアプリケーションへリダイレクトされず、代わりに汎用的な Auth0 ページが表示されます。コールバック URL の形式は {customScheme}://{yourDomain}/{platform}/{bundleIdentifier or packageName}/callback です。URL スキームには app.jsoncustomScheme が使用されますが、パスには常に bundleIdentifier (iOS) または package (Android) が含まれ、カスタムスキームは含まれません。customScheme を指定しない場合、SDK は URL スキームとしてデフォルトで {bundleIdentifier}.auth0 / {packageName}.auth0 を使用します。
重要: コールバック URL の customSchemeapp.json のプラグイン設定内の値と完全に一致し、パスに実際の bundleIdentifier (iOS) または package (Android) が含まれていることを確認してください。値が一致しないと、認証は失敗します。
5

App コンポーネントをセットアップする

選択した実装方法に応じて、メインのアプリコンポーネントを設定します。
App.js の内容を置き換え、アプリケーションを Auth0Provider コンポーネントで囲みます。
App.js
import React from 'react';
import {Auth0Provider, useAuth0} from 'react-native-auth0';
import {
  StyleSheet,
  Text,
  View,
  Button,
  Image,
  ActivityIndicator,
} from 'react-native';

function HomeScreen() {
  const {authorize, clearSession, user, isLoading} = useAuth0();

  const handleLogin = async () => {
    try {
      await authorize({customScheme: 'auth0sample', scope: 'openid profile email'});
    } catch (e) {
      console.error('Login error:', e);
    }
  };

  const handleLogout = async () => {
    try {
      await clearSession({customScheme: 'auth0sample'});
    } catch (e) {
      console.error('Logout error:', e);
    }
  };

  if (isLoading) {
    return (
      <View style={styles.container}>
        <ActivityIndicator size="large" color="#0066cc" />
        <Text style={styles.loadingText}>Loading...</Text>
      </View>
    );
  }

  return (
    <View style={styles.container}>
      <Text style={styles.title}>Auth0 Expo Sample</Text>

      {user ? (
        <View style={styles.profileContainer}>
          {user.picture && (
            <Image source={{uri: user.picture}} style={styles.avatar} />
          )}
          <Text style={styles.welcomeText}>Welcome, {user.name}!</Text>
          <Text style={styles.emailText}>{user.email}</Text>
          <View style={styles.buttonContainer}>
            <Button title="Log Out" onPress={handleLogout} color="#dc3545" />
          </View>
        </View>
      ) : (
        <View style={styles.loginContainer}>
          <Text style={styles.subtitle}>
            Tap the button below to log in
          </Text>
          <View style={styles.buttonContainer}>
            <Button title="Log In" onPress={handleLogin} color="#0066cc" />
          </View>
        </View>
      )}
    </View>
  );
}

export default function App() {
  return (
    <Auth0Provider domain="{yourDomain}" clientId="{yourClientId}">
      <HomeScreen />
    </Auth0Provider>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
    padding: 20,
    backgroundColor: '#fff',
  },
  title: {
    fontSize: 28,
    fontWeight: 'bold',
    marginBottom: 20,
    color: '#333',
  },
  subtitle: {
    fontSize: 16,
    color: '#666',
    marginBottom: 30,
    textAlign: 'center',
  },
  loadingText: {
    marginTop: 10,
    fontSize: 16,
    color: '#666',
  },
  profileContainer: {
    alignItems: 'center',
  },
  avatar: {
    width: 100,
    height: 100,
    borderRadius: 50,
    marginBottom: 20,
  },
  welcomeText: {
    fontSize: 22,
    fontWeight: '600',
    marginBottom: 8,
    color: '#333',
  },
  emailText: {
    fontSize: 16,
    color: '#666',
    marginBottom: 30,
  },
  loginContainer: {
    alignItems: 'center',
  },
  buttonContainer: {
    width: 200,
    marginTop: 10,
  },
});
{yourDomain} は Auth0 のドメインに、{yourClientId} は Auth0 Dashboard のクライアントIDに置き換えます。
Auth0Provider は SDK を初期化し、useAuth0 フックを通じてすべての子コンポーネントに認証コンテキストを提供します。customScheme パラメーターは、app.json のプラグイン設定の値と一致する必要があります。
authorize() メソッドは、安全なブラウザー (iOS では ASWebAuthenticationSession、Android では Chrome Custom Tabs) で Auth0 の Universal Login を開きます。clearSession() メソッドはユーザーをログアウトし、ブラウザーのセッションと保存された認証情報の両方を消去します。customScheme パラメーターは、app.json のプラグイン設定の値と一致している必要があります。
6

アプリを実行する

Expo アプリをデバイスまたはエミュレーターでビルドして実行します。まず、ネイティブの iOS プロジェクトと Android プロジェクトを生成します。
npx expo prebuild
次に、対象プラットフォームで実行します。iOS の場合:
npx expo run:ios
Android の場合:
npx expo run:android
想定されるフロー:
  1. アプリが起動し、“Log In” ボタンが表示される
  2. Log In をタップ → Auth0 Universal Login をブラウザーで開く
  3. ログインを完了する (サインアップまたはサインイン)
  4. ブラウザーが閉じる → 自動的にアプリに戻る
  5. 名前、メールアドレス、アバターを含むユーザープロフィールが表示される
app.json のプラグイン設定を変更した場合は、npx expo prebuild --clean を実行して、更新後の設定でネイティブプロジェクトを再生成してください。
iOS Simulator で ASWebAuthenticationSession を使用するには、有効な Apple Developer アカウントが必要です。アカウントなしでシミュレーター上でテストする場合は、代わりに実機または Android エミュレーターを使用してください。
チェックポイントこれで、デバイスまたはエミュレーター上で Auth0 のログイン機能が完全に動作しているはずです。このアプリは安全なブラウザー認証を使用し、認証情報をデバイスのセキュアストレージで自動的に管理します。

トラブルシューティングと高度な設定

”Invariant Violation: Native module cannot be null”

このエラーは、Expo Go で SDK を使用しようとすると発生します。解決策:Auth0 SDK では、Expo Go では利用できないカスタムネイティブコードが必要です。代わりに開発用ビルドを使用してください。
npx expo run:ios
# または
npx expo run:android

コールバック URL の不一致エラー

解決策:次の 3 つがすべて完全に一致していることを確認してください。
  1. app.json のプラグイン設定内の customScheme
  2. authorize()clearSession() に渡す customScheme パラメーター
  3. Auth0 Dashboard のコールバック URL (Applications → Your App → Settings → Application URIs)

“PKCE not allowed” エラー

修正方法:
  1. Auth0 Dashboard → Applications → Your Application に移動します
  2. アプリケーションタイプを Native に変更します
  3. 変更を保存して、再度試してください

Prebuild が失敗する、またはプラグインが適用されない

修正方法:
# ネイティブプロジェクトをクリーンアップして再生成
npx expo prebuild --clean

iOS ビルドが Pod エラーで失敗する

修正方法:
cd ios
pod install --repo-update
cd ..
npx expo run:ios

ユーザーによるキャンセル エラー

ログイン関数で適切に処理してください。
const handleLogin = async () => {
  try {
    await authorize({customScheme: 'auth0sample', scope: 'openid profile email'});
  } catch (e) {
    if (e.message === 'a0.session.user_cancelled') {
      // ユーザーがログイン画面を閉じた場合の処理
      console.log('ユーザーによってログインがキャンセルされました');
    } else {
      console.error('ログインに失敗しました:', e);
    }
  }
};

iOS のアラートダイアログ

iOS では、“App Name” Wants to Use “auth0.com” to Sign In という許可ダイアログが表示されます。これは ASWebAuthenticationSession の想定された動作です。続行するには、ユーザーが Continue をタップする必要があります。この動作を変更するには、エフェメラルセッションを使用できます (SSO は無効になります) 。
await authorize({customScheme: 'auth0sample', scope: 'openid profile email'}, {ephemeralSession: true});
API 呼び出しに使用するトークンを取得するには、getCredentials() メソッドを使用します。
import {useAuth0} from 'react-native-auth0';

const MyComponent = () => {
  const {getCredentials} = useAuth0();

  const callApi = async () => {
    try {
      const credentials = await getCredentials();
      const response = await fetch('https://your-api.com/endpoint', {
        headers: {
          Authorization: `Bearer ${credentials.accessToken}`,
        },
      });
      // レスポンスを処理
    } catch (e) {
      console.error('認証情報の取得に失敗しました', e);
    }
  };
};
リフレッシュトークンを受け取るには、ログイン時に offline_access スコープを含めてください: authorize({customScheme: 'auth0sample', scope: 'openid profile email offline_access'})。これにより、トークンの自動更新が有効になります。
ユーザーがすでにログインしているかどうかを確認するには、hasValidCredentials() を使用します。
import {useAuth0} from 'react-native-auth0';
import {useEffect} from 'react';

const App = () => {
  const {hasValidCredentials, getCredentials} = useAuth0();

  useEffect(() => {
    const checkAuth = async () => {
      const isLoggedIn = await hasValidCredentials();
      if (isLoggedIn) {
        const credentials = await getCredentials();
        // ユーザーは認証済みのため、そのデータを読み込む
      }
    };
    checkAuth();
  }, []);
};
本番ビルドでは、ローカルの開発ビルドではなく EAS Build を使用します。EAS CLI をインストールします。
npm install -g eas-cli
プロジェクトのルートに eas.json を作成します。
eas.json
{
  "cli": {
    "version": ">= 3.0.0"
  },
  "build": {
    "development": {
      "developmentClient": true,
      "distribution": "internal"
    },
    "preview": {
      "distribution": "internal"
    },
    "production": {}
  }
}
本番用にビルドします。
# 両方のプラットフォーム向けにビルド
eas build --platform all

# または特定のプラットフォーム向けにビルド
eas build --platform ios
eas build --platform android

本番環境にデプロイする前に

セキュリティを強化するため、HTTPS コールバック URL を使用します。
https://{yourDomain}/ios/{bundleId}/callback
https://{yourDomain}/android/{packageName}/callback
Auth0 Dashboard で Android App Links を設定します。
  • Settings → Advanced Settings → Device Settings
  • アプリの SHA-256 フィンガープリントを追加します
iOS Universal Links を設定します。
  • Xcode で Associated Domains 機能を追加します
  • Associated Domains に webcredentials:{yourDomain} を追加します
Auth0 Dashboard で セキュリティ設定 を確認します。
  • Advanced Settings で OIDC Conformant を有効にします
  • トークンの有効期限 を適切に設定します
  • 総当たり攻撃対策 を設定します
  • 複数のデバイスと OS バージョンでテストします
  • ネットワーク障害に対する適切なエラーハンドリングを実装します
本番アプリでは、セキュリティ強化のため、カスタムスキームではなく、Universal Links (iOS) や App Links (Android) を使用する HTTPS コールバック URL の利用を検討してください。