> ## Documentation Index
> Fetch the complete documentation index at: https://docs-staging.auth0-mintlify.app/llms.txt
> Use this file to discover all available pages before exploring further.

# Auth0 Kotlin Multiplatform SDKを使用してKotlin MultiplatformアプリケーションにLoginを追加する

> Auth0 Kotlin Multiplatform SDKを使用して、Kotlin Multiplatform（Android + iOS）アプリに認証を追加します。

export const HowToSchema = () => <script type="application/ld+json">
    {'{"@context":"https://schema.org","@type":"HowTo"}'}
  </script>;

<HowToSchema />

<Accordion title="AI を使って Auth0 と連携する" icon="microchip-ai" iconType="solid" defaultOpen>
  Claude Code、Cursor、GitHub Copilot などの AI コーディングアシスタントをお使いの場合は、[agent skills](https://agentskills.io/home) を利用して、数分で Auth0 認証 を自動的に追加できます。

  **インストール：**

  ```bash theme={null}
  npx skills add auth0/agent-skills --skill auth0
  ```

  **続いて、AI アシスタントに次のように依頼します：**

  ```text theme={null}
  Add Auth0 authentication to my Kotlin Multiplatform app.
  ```

  AI アシスタントが、Auth0 アプリケーションの作成、資格情報の取得、Auth0 Kotlin Multiplatform SDK の dependency の追加、Android の manifest placeholders と iOS の URL スキームの設定、Login/ログアウト flows の実装までを自動的に行います。[agent skills の詳細なドキュメントを読む](/docs/ja-jp/quickstart/agent-skills)。
</Accordion>

<Note>
  このクイックスタートは、Kotlin Multiplatform 2.0 以降、Android SDK 24 以降 (Android 7.0) 、iOS 14 以降でご利用ください。Auth0 Kotlin Multiplatform SDK は現在 1.0.0-beta.0 です。安定版のリリースまでに API が変更される可能性があるため、このバージョンを明示的に固定してください。また、[Android Studio](https://developer.android.com/studio) (Ladybug 以降) が必要です。iOS ターゲットの場合は、macOS 上の [Xcode 15+](https://developer.apple.com/xcode/) も必要です。
</Note>

<h2 id="get-started">
  はじめる
</h2>

このクイックスタートでは、Kotlin Multiplatformアプリを構成し、エンドユーザーがAuth0の[Universal Login](/docs/ja-jp/authenticate/login/auth0-universal-login)を使ってログイン・ログアウトできるようにし、トークンを安全に保存し、ユーザープロファイルを表示する方法を説明します。これらはすべて、AndroidとiOSの両方で動作する共有Kotlinコードから実現できます。

<Steps>
  <Step title="新しい Kotlin Multiplatform プロジェクトを作成する" stepNumber={1}>
    すでに Kotlin Multiplatform プロジェクトをお持ちの場合は、次のステップに進んでください。

    [JetBrains Kotlin Multiplatform ウィザード](https://kmp.jetbrains.com/) (**Android** と **iOS** を選択し、**Compose Multiplatform** で UI を共有) 、または Android Studio の **Kotlin Multiplatform** プラグインを使用して、Compose UI を共有する新しい Kotlin Multiplatform プロジェクトを作成します。

    これにより、本ガイド全体で参照する標準的なレイアウトが生成されます。

    ```text theme={null}
    your-app/
    ├── composeApp/
    │   ├── build.gradle.kts
    │   └── src/
    │       ├── commonMain/kotlin/    ← 共有コード（Auth0 クライアント、ビューモデル、UI）
    │       ├── androidMain/          ← Android のエントリーポイント + AndroidManifest.xml
    │       └── iosMain/kotlin/       ← iOS のエントリーポイント
    ├── iosApp/                       ← Xcode プロジェクト（Info.plist はここに配置）
    └── settings.gradle.kts
    ```

    <Info>
      このガイドでは、アプリケーション ID / バンドル識別子として `com.example.app` を使用しています。この値は Auth0 のコールバック URL の一部になるため、プレースホルダーをご自身の値に置き換えてください。
    </Info>
  </Step>

  <Step title="Gradle を使用して Auth0 SDK を追加" stepNumber={2}>
    共有モジュールの `commonMain` ソースセットに Auth0 Kotlin Multiplatform SDK を追加します。このライブラリは Maven Central で公開されているため、追加のリポジトリ設定は必要ありません。

    **`composeApp/build.gradle.kts` を更新します:**

    ```kotlin composeApp/build.gradle.kts theme={null}
    kotlin {
        sourceSets {
            commonMain.dependencies {
                // アンブレラモジュール — Web Auth、認証、資格情報をまとめて提供
                implementation("com.auth0.kmp:auth0:1.0.0-beta.0")
            }
        }
    }
    ```

    <Tip>
      包括的なアーティファクトである `auth0` には、必要なものがすべて含まれています。フットプリントを小さく抑えたい場合は、代わりに次の個別モジュールを依存関係に指定することもできます: `auth0-core`、`auth0-webauth`、`auth0-authentication`、`auth0-credentials`。
    </Tip>
  </Step>

  <Step title="Auth0 App を設定する" stepNumber={3}>
    Auth0 で Native アプリケーションを作成し、Android と iOS の両方について、プラットフォーム固有のコールバック URL とログアウト URL を登録します。

    1. [Auth0 Dashboard](https://manage.auth0.com/dashboard/) にアクセスします。
    2. **アプリケーション** > **アプリケーション** > **Create Application** を選択します。
    3. ポップアップでアプリの名前を入力し、アプリの種類として **Native** を選択して、**Create** を選択します。
    4. アプリケーション詳細ページの設定タブに切り替え、Domain と Client ID をコピーします。これらは後の手順でコードに追加します。

    続けて設定タブで、次の URL を設定します。コールバックの形式はプラットフォームごとのスキームによって異なるため、Android 用と iOS 用にそれぞれ 1 つずつ登録してください。

    **Allowed Callback URLs：**

    ```
    com.example.app://{yourDomain}/android/com.example.app/callback, com.example.app://{yourDomain}/ios/com.example.app/callback
    ```

    **許可するログアウト URL:**

    ```
    com.example.app://{yourDomain}/android/com.example.app/callback, com.example.app://{yourDomain}/ios/com.example.app/callback
    ```

    `{yourDomain}` を実際の Auth0 ドメイン (例：`dev-abc123.us.auth0.com`) に、`com.example.app` をアプリケーション ID / バンドル識別子に置き換えてください。

    <Info>
      Allowed Callback URLs は、認証後にエンドユーザーを安全にアプリケーションへ戻すための設定です。一致する URL がない場合、ログインプロセスは失敗します。Allowed Logout URLs は、サインアウト後にユーザーをアプリへリダイレクトさせるための設定です。

      コールバックの形式には、パッケージ / バンドル識別子が埋め込まれます。Android では `SCHEME://YOUR_DOMAIN/android/APPLICATION_ID/callback`、iOS では `SCHEME://YOUR_DOMAIN/ios/BUNDLE_ID/callback` です。既定では、スキームはアプリケーション ID / バンドル識別子と同じ値になります。
    </Info>

    <Note>
      **重要**：コールバック URL に含まれるパッケージ / バンドル名が、`applicationId` (Android) およびバンドル識別子 (iOS) と完全に一致していることを確認してください。認証に失敗する場合は、これらの値が同一かどうかを確認してください。
    </Note>
  </Step>

  <Step title="各プラットフォームでコールバック用スキームを登録する" stepNumber={4}>
    SDK には `RedirectActivity` (Android、自動的にマージされます) が同梱されており、iOS では `ASWebAuthenticationSession` を使ってコールバックを受け取ります。必要な作業は、各プラットフォームで URL スキームを宣言することだけです。

    **Android**: Android のビルドファイルに manifest placeholders を追加します。SDK の `RedirectActivity` がこれらの値を読み取ります:

    ```kotlin composeApp/build.gradle.kts theme={null}
    android {
        defaultConfig {
            
            manifestPlaceholders["auth0Scheme"] = "{yourScheme}" // デフォルト: アプリケーション ID
            manifestPlaceholders["auth0Domain"] = "{yourDomain}"
        }
    }
    ```

    また、`AndroidManifest.xml` でインターネットの permission を request していることも確認してください:

    ```xml composeApp/src/androidMain/AndroidManifest.xml theme={null}
    <?xml version="1.0" encoding="utf-8"?>
    <manifest xmlns:android="http://schemas.android.com/apk/res/android">
        <uses-permission android:name="android.permission.INTERNET" />
    </manifest>
    ```

    **iOS**: `iosApp/iosApp/Info.plist` に URL スキームを登録します (または Xcode → ターゲット → **Info** → **URL Types** から登録) :

    ```xml iosApp/iosApp/Info.plist theme={null}
    <key>CFBundleURLTypes</key>
    <array>
        <dict>
            <key>CFBundleTypeRole</key>
            <string>Editor</string>
            <key>CFBundleURLSchemes</key>
            <array>
                <!-- Bundle Identifier と一致している必要があります -->
                <string>com.example.app</string>
            </array>
        </dict>
    </array>
    ```
  </Step>

  <Step title="Auth0 SDK を初期化する" stepNumber={5}>
    共有の`commonMain`ソースセットでは、`Auth0`クライアントを一度だけ作成して再利用します。このクライアントは、Web Auth、[Authentication API](/docs/ja-jp/api/authentication)、資格情報マネージャーが共有するトランスポートを保持します。

    **`composeApp/src/commonMain/kotlin/Auth0Config.kt`を作成します：**

    ```kotlin composeApp/src/commonMain/kotlin/Auth0Config.kt theme={null}
    import com.auth0.kmp.Auth0
    import com.auth0.kmp.core.Auth0Account

    // 共有コード — 1つのアカウントでAndroidとiOSの両方に対応
    val account = Auth0Account(
        clientId = "YOUR_AUTH0_CLIENT_ID", // Application Settings → Client ID から取得
        domain = "{yourDomain}",           // Application Settings → Domain から取得
    )

    val auth0 = Auth0(account)
    ```

    <Info>
      本番環境では、資格情報をソースコードにハードコーディングしないでください。[サンプルアプリ](https://github.com/auth0/auth0-kmp/tree/main/sample-app)では、`local.properties`から`auth0.domain`と`auth0.clientId`を読み取り、生成された構成経由で公開しています。DomainとClient IDは、どちらもAuth0 DashboardのApplication Settingsから取得できます。ドメインに`https://`スキームを含めないでください。
    </Info>
  </Step>

  <Step title="Login と Logout の実装" stepNumber={6}>
    Auth0 Kotlin Multiplatform のすべてのメソッドは、`Result<Success, Error>` を返すコルーチンの `suspend` 関数です。ドメインエラーで例外がスローされることはありません。Compose の UI から state を監視できるよう、呼び出しを `ViewModel` でラップしてください。

    **`composeApp/src/commonMain/kotlin/AuthViewModel.kt` を作成します:**

    ```kotlin composeApp/src/commonMain/kotlin/AuthViewModel.kt theme={null}
    import androidx.lifecycle.ViewModel
    import androidx.lifecycle.viewModelScope
    import com.auth0.kmp.core.result.Result
    import kotlinx.coroutines.flow.MutableStateFlow
    import kotlinx.coroutines.flow.StateFlow
    import kotlinx.coroutines.flow.asStateFlow
    import kotlinx.coroutines.launch

    sealed interface AuthState {
        data object LoggedOut : AuthState
        data object Loading : AuthState
        data class LoggedIn(val accessToken: String) : AuthState
        data class Error(val message: String) : AuthState
    }

    class AuthViewModel(val auth0: Auth0) : ViewModel() {
        
        // トークンを永続化し、自動更新します（AndroidではKeystore/DataStore、iOSではKeychain）
        private val credentialsManager = auth0.credentials()

        private val _state = MutableStateFlow<AuthState>(AuthState.LoggedOut)
        val state: StateFlow<AuthState> = _state.asStateFlow()

        fun login() {
            viewModelScope.launch {
                _state.value = AuthState.Loading
                // システムブラウザーでUniversal Loginを開きます
                when (val result = auth0.webAuth.login()) {
                    is Result.Success -> {
                        credentialsManager.saveCredentials(result.data)
                        _state.value = AuthState.LoggedIn(result.data.accessToken)
                    }
                    is Result.Failure -> {
                        _state.value = AuthState.Error(result.error.toString())
                    }
                }
            }
        }

        fun logout() {
            viewModelScope.launch {
                // ブラウザーのセッションを消去し、続いてローカルに保存された資格情報を消去します
                when (val result = auth0.webAuth.logout()) {
                    is Result.Success -> {
                        credentialsManager.clearCredentials()
                        _state.value = AuthState.LoggedOut
                    }
                    is Result.Failure -> {
                        _state.value = AuthState.Error(result.error.toString())
                    }
                }
            }
        }
    }
    ```

    両プラットフォームで共有する Compose 画面にビューモデルを組み込みます。

    ```kotlin composeApp/src/commonMain/kotlin/App.kt theme={null}
    import androidx.compose.material3.Button
    import androidx.compose.material3.CircularProgressIndicator
    import androidx.compose.material3.MaterialTheme
    import androidx.compose.material3.Text
    import androidx.compose.runtime.Composable
    import androidx.compose.runtime.getValue
    import androidx.lifecycle.compose.collectAsStateWithLifecycle
    import androidx.lifecycle.viewmodel.compose.viewModel

    @Composable
    fun App(viewModel: AuthViewModel = viewModel { AuthViewModel() }) {
        MaterialTheme {
            val state by viewModel.state.collectAsStateWithLifecycle()
            when (val current = state) {
                is AuthState.Loading -> CircularProgressIndicator()
                is AuthState.LoggedIn -> Button(onClick = viewModel::logout) { Text("Log Out") }
                is AuthState.Error -> Text("Something went wrong: ${current.message}")
                AuthState.LoggedOut -> Button(onClick = viewModel::login) { Text("Log In") }
            }
        }
    }
    ```
  </Step>

  <Step title="ユーザープロファイルを表示する" stepNumber={7}>
    ログイン後、アクセストークンを使ってAuthentication APIの`userInfo`を呼び出し、認証されたユーザーのプロファイルを取得します。

    ```kotlin composeApp/src/commonMain/kotlin/AuthViewModel.kt theme={null}
    import com.auth0.kmp.authentication.UserInfo

    suspend fun fetchProfile(accessToken: String): UserInfo? {
        return when (val result = auth0.authentication.userInfo(accessToken)) {
            is Result.Success -> result.data // .name, .email, .picture, .customClaims, ...
            is Result.Failure -> null
        }
    }
    ```

    <Info>
      アプリの起動時に有効な資格情報がすでに存在する場合は、ログイン画面をスキップできます。保存済みで有効期限内のセッションが利用可能な場合、`credentialsManager.hasValidCredentials()` は `true` を返します。`credentialsManager.getCredentials()` を使用すると有効なアクセストークンを取得でき、必要に応じて[リフレッシュトークン](/docs/ja-jp/secure/tokens/refresh-tokens)によってアクセストークンが自動的に更新されます。
    </Info>
  </Step>

  <Step title="アプリを実行する" stepNumber={8}>
    各ターゲットでビルドしてローンチします。

    <CodeGroup>
      ```shellscript Android theme={null}
      ./gradlew :composeApp:installDebug
      ```

      ```shellscript iOS theme={null}
      # Xcode プロジェクトを開き、シミュレーターまたは実機で実行します
      open iosApp/iosApp.xcodeproj
      ```
    </CodeGroup>

    **想定されるフロー：**

    1. アプリが起動し、"Log In" ボタンが表示されます。
    2. "Log In" をタップ → システムブラウザーで Auth0 Universal Login ページが開く → ログインを完了します。
    3. 自動的にアプリに制御が戻り、ボタンが "Log Out" に切り替わります。
    4. 成功です！
  </Step>
</Steps>

<Check>
  **チェックポイント**

  これで、Auth0 によるLogin、ログアウト、セキュアなトークン保存、ユーザープロファイルの取得を備えた Compose Multiplatform アプリが完成しました。認証ロジックはすべて Android と iOS で共有されています。
</Check>

***

<h2 id="troubleshooting-advanced">
  トラブルシューティングと高度な設定
</h2>

<Accordion title="コールバック URL の不一致エラー">
  **原因:** SDK が生成するコールバック URL が Auth0 アプリケーションに登録されていない、またはスキームやパッケージが一致していません。

  **対処:** Application Settings の Allowed Callback URLs が、プラットフォームごとの形式と完全に一致していることを確認してください。Android では `SCHEME://YOUR_DOMAIN/android/APPLICATION_ID/callback`、iOS では `SCHEME://YOUR_DOMAIN/ios/BUNDLE_ID/callback` です。`SCHEME` (既定値: アプリケーション ID) とパッケージ/バンドルは、プロジェクトの値と完全に同一である必要があります。URL は大文字と小文字が区別され、スキームは小文字でなければなりません。
</Accordion>

<Accordion title="ブラウザーは開くがアプリに戻ってこない">
  **原因:** コールバックスキームがプラットフォーム側で宣言されていないため、OS がリダイレクトをアプリに戻せません。

  **対処:** Android では、`composeApp/build.gradle.kts` に `manifestPlaceholders["auth0Scheme"]` と `["auth0Domain"]` が設定されていることを確認し、クリーンビルドを実行してください。iOS では、`Info.plist` の `CFBundleURLSchemes` エントリーがバンドル識別子と一致していることを確認してください。
</Accordion>

<Accordion title="Loginがネットワークエラーやタイムアウトエラーで Result.Failure を返す">
  **原因:** デバイスが Auth0 テナントに到達できない、またはリクエストがタイムアウトしています。

  **対処:** `Auth0Account` の `domain` が、`https://` スキームを含まないテナントドメイン (例: `your-tenant.us.auth0.com`) になっていることを確認してください。実機の場合は、ネットワークに接続できているか確認してください。タイムアウト値は、`Auth0Account` に渡す `NetworkingConfiguration` で引き上げられます。
</Accordion>

<Accordion title="Login後に getCredentials が失敗する">
  **原因:** リフレッシュトークンが発行されていないため、期限切れの資格情報を更新できません。

  **対処:** Universal Login は既定で `offline_access` scope を要求します (これによりリフレッシュトークンが返されます) 。`LoginOptions` で `scope` を上書きする場合は `offline_access` を含め、Auth0 Dashboard で該当アプリケーションの **Refresh Tokenのローテーション** を有効にしてください。
</Accordion>

<Accordion title="Android ビルドで RedirectActivity のマージに失敗する">
  **原因:** `auth0Domain` / `auth0Scheme` の manifest placeholders が指定されていないため、SDK がマージする `RedirectActivity` にバインドする値がありません。

  **対処:** `composeApp/build.gradle.kts` の `defaultConfig` ブロックに両方のプレースホルダーが定義されていることを確認してください。複数のビルドフレーバーを使用している場合は、各フレーバーで定義してください。
</Accordion>

<Accordion title="起動時にセッションを復元する">
  Login画面を表示する前に保存された資格情報を確認し、再訪ユーザーが Universal Login をスキップできるようにします:

  ```kotlin theme={null}
  if (credentialsManager.hasValidCredentials()) {
      val credentials = credentialsManager.getCredentials() // 期限切れの場合は自動更新される
      // 認証済みの画面へ遷移する
  }
  ```
</Accordion>

<Accordion title="access token で自社の API を呼び出す">
  Auth0 が自社 API 向けの access token を発行するように audience を指定してリクエストします:

  ```kotlin theme={null}
  import com.auth0.kmp.webauth.LoginOptions

  auth0.webAuth.login(
      LoginOptions(
          audience = "https://your-api.example.com", // API Settings → Identifier の値
          scope = "openid profile email offline_access",
      ),
  )
  ```
</Accordion>

<Accordion title="フェデレーテッドログアウト">
  Auth0 だけでなく、上流のアイデンティティプロバイダーからもユーザーをログアウトさせます:

  ```kotlin theme={null}
  import com.auth0.kmp.webauth.LogoutOptions

  auth0.webAuth.logout(LogoutOptions(federated = true))
  ```
</Accordion>

<h2 id="next-steps">
  次のステップ
</h2>

* [Auth0 Kotlin Multiplatform SDK](https://github.com/auth0/auth0-kmp)の全機能と、Organizations、DPoP、パスキー、カスタムストレージを扱った`EXAMPLES.md`を確認する。
* [Android + iOSサンプルアプリ](https://github.com/auth0/auth0-kmp/tree/main/sample-app)の完全版を実行してみる。
* [Auth0 Universal Login](/docs/ja-jp/authenticate/login/auth0-universal-login)と[リフレッシュトークン](/docs/ja-jp/secure/tokens/refresh-tokens)について詳しく学ぶ。
