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

> Auth0.swift でユーザーのログイン状態を維持する

# Auth0.swift: トークンの保存と更新

`offline_access` スコープを含めて認証を行うと、<Tooltip tip="Refresh Token: ユーザーに再度ログインを求めることなく、新しいアクセストークンを取得するために使用されるトークン。" cta="用語集を見る" href="/docs/ja-jp/glossary?term=Refresh+Token">リフレッシュトークン</Tooltip> が返されます。これを使うと、資格情報を再度求めることなく新しいトークンをリクエストできます。

<div id="credentials-manager">
  ## Credentials Manager
</div>

[Auth0.swift](https://github.com/auth0/Auth0.swift) には、資格情報の保存と更新を簡単に行うためのユーティリティクラスが用意されています。[資格情報](https://github.com/auth0/Auth0.swift/blob/master/Auth0/Credentials.swift) インスタンスから `accessToken` または `idToken` プロパティにアクセスできます。これは、ユーザーの資格情報を管理するための推奨方法です。

まず、`Auth0` モジュールをインポートします。

`import Auth0`

次に、<Tooltip tip="Universal Login: ユーザーのアイデンティティを確認するため、アプリケーションは Auth0 の認可サーバーでホストされている Universal Login にリダイレクトされます。" cta="用語集を見る" href="/docs/ja-jp/glossary?term=Universal+Login">Universal Login</Tooltip> ページを表示します。

```swift lines theme={null}
let credentialsManager = CredentialsManager(authentication: Auth0.authentication())

Auth0
    .webAuth()
    .scope("openid profile offline_access")
    .start { result in
        switch result {
        case .success(let credentials):
            // 資格情報をCredentials Managerに渡す
            credentialsManager.store(credentials: credentials)
        case .failure(let error):
            // エラーを処理する
        }
}
```

<Warning>
  アプリをアンインストールしても、Keychain の項目は削除されません。そのため、初回起動時にアプリの Keychain 項目を必ずすべて消去することをおすすめします。
</Warning>

<div id="credentials-check">
  ### 資格情報の確認
</div>

アプリの起動時に簡単なチェックを行い、更新可能な資格情報がマネージャーに保存されていることを確認しておくと便利です。保存されていない場合は、ユーザーに認証を促すことができます。

```swift lines theme={null}
guard credentialsManager.canRenew() else {
    // ログインページを表示する
}
```

<div id="retrieving-user-credentials">
  ### ユーザー資格情報の取得
</div>

次のようにして、ユーザーの資格情報を取得できます。

```swift lines theme={null}
credentialsManager.credentials { result in 
    switch result {
    case .success(let credentials):
        // 有効な資格情報です。`idToken`、`accessToken` などのトークンプロパティにアクセスできます
    case .failure(let error):
        // エラーを処理し、ログインページを表示します
    }
}
```

token の有効期限が切れている場合でも、ユーザーの資格情報の更新方法はまったく同じです。Credentials Manager は資格情報を自動的に更新し、更新後の資格情報を Keychain に保存したうえで、資格情報またはエラーのいずれかを含む `Result` を返します。

<div id="alternative-method-simplekeychain">
  ## 代替方法 - SimpleKeychain
</div>

このセクションは、Credentials Manager を使いたくない開発者向けです。トークンを安全に保存できるよう、システムの Keychain を簡単に扱える軽量なラッパーである SimpleKeychain を用意しています。

まず、`SimpleKeychain` モジュールをインポートします。

`import SimpleKeychain`

次に、インスタンスを作成して必要なトークンを保存します。この場合は、認証が正常に完了した後、`access_token` と `refresh_token` を Keychain に保存します。

```swift lines theme={null}
let keychain = SimpleKeychain(service: "Auth0")

Auth0
    .webAuth()
    .scope("openid profile offline_access")
    .start { result in
        switch result {
        case .success(let credentials):
            guard let refreshToken = credentials.refreshToken else { 
                // エラーを処理する 
                return
            }
            // トークンを保存する
            do {
                try keychain.set(credentials.accessToken, forKey: "access_token")
                try keychain.set(refreshToken, forKey: "refresh_token")
            } catch {
                // エラーを処理する
            }
            // この時点でアプリのメインフローに遷移するとよいでしょう
        case .failure(let error):
            // エラーを処理する
        }
}
```

それらを保存しておけば、いつでも新しい[資格情報](https://github.com/auth0/Auth0.swift/blob/master/Auth0/Credentials.swift)インスタンスを取得できます。

<div id="renewing-user-credentials">
  ### ユーザーの資格情報の更新
</div>

```swift lines expandable theme={null}
let keychain = SimpleKeychain(service: "Auth0")

Auth0
    .authentication()
    .renew(withRefreshToken: refreshToken)
    .start { result in
        switch(result) {
        case .success(let credentials):
            // Refresh Tokenのローテーションが有効な場合、新しいリフレッシュトークンが発行されます
            // 無効な場合は新しいアクセストークンのみが発行されます
            guard let refreshToken = credentials.refreshToken else { 
                // エラー処理
                return
            }
            // 新しいトークンを保存する
            do {
                try keychain.set(credentials.accessToken, forKey: "access_token")
                try keychain.set(refreshToken, forKey: "refresh_token")
            } catch {
                // エラー処理
            }
        case .failure(let error):
            // エラー処理
        }
}
```
