> ## 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.

> /oauth/ro から /oauth/token へのパスワードレス API の呼び出しとレスポンスの移行方法を説明します。

# リソース所有者のパスワードレス資格情報交換を移行する

export const AuthCodeBlock = ({filename, icon, language, highlight, children}) => {
  const [displayText, setDisplayText] = useState(children);
  const [copyText, setCopyText] = useState(children);
  const wrapperRef = React.useRef(null);
  useEffect(() => {
    let unsubscribe = null;
    function init() {
      if (!window.autorun || !window.rootStore) {
        return;
      }
      unsubscribe = window.autorun(() => {
        let processedChildrenForDisplay = children;
        let processedChildrenForCopy = children;
        for (const [key, value] of window.rootStore.variableStore.values.entries()) {
          const escapedKey = key.replaceAll(/[.*+?^${}()|[\]\\]/g, (String.raw)`\$&`);
          let displayValue = value;
          if (key === "{yourClientSecret}" && value !== "{yourClientSecret}") {
            displayValue = value.substring(0, 3) + "*****MASKED*****";
          }
          processedChildrenForDisplay = processedChildrenForDisplay.replaceAll(new RegExp(escapedKey, "g"), displayValue);
          processedChildrenForCopy = processedChildrenForCopy.replaceAll(new RegExp(escapedKey, "g"), value);
        }
        setDisplayText(processedChildrenForDisplay);
        setCopyText(processedChildrenForCopy);
      });
    }
    if (window.rootStore) {
      init();
    } else {
      window.addEventListener("adu:storeReady", init);
    }
    return () => {
      window.removeEventListener("adu:storeReady", init);
      unsubscribe?.();
    };
  }, [children]);
  useEffect(() => {
    if (!wrapperRef.current) return;
    const originalWriteText = navigator.clipboard.writeText.bind(navigator.clipboard);
    let isOverriding = false;
    const handleClick = e => {
      const button = e.target.closest('[data-testid="copy-code-button"]');
      if (!button || !wrapperRef.current.contains(button)) return;
      isOverriding = true;
      navigator.clipboard.writeText = text => {
        if (isOverriding) {
          isOverriding = false;
          navigator.clipboard.writeText = originalWriteText;
          return originalWriteText(copyText);
        }
        return originalWriteText(text);
      };
      setTimeout(() => {
        if (isOverriding) {
          isOverriding = false;
          navigator.clipboard.writeText = originalWriteText;
        }
      }, 100);
    };
    const wrapper = wrapperRef.current;
    wrapper.addEventListener('click', handleClick, true);
    return () => {
      wrapper.removeEventListener('click', handleClick, true);
      if (navigator.clipboard.writeText !== originalWriteText) {
        navigator.clipboard.writeText = originalWriteText;
      }
    };
  }, [copyText]);
  return <div ref={wrapperRef}>
      <CodeBlock filename={filename} icon={icon} language={language} lines highlight={highlight}>
        {displayText}
      </CodeBlock>
    </div>;
};

`/oauth/token` で、<Tooltip tip="リソース所有者: 保護されたリソースへのアクセスを許可できる主体（ユーザーやアプリケーションなど）。" cta="用語集を見る" href="/docs/ja-jp/glossary?term=resource+owner">リソース所有者</Tooltip>パスワードがサポートされるようになりました。`/oauth/ro` エンドポイントの使用は 2017 年 7 月 8 日に非推奨となりました。`/oauth/ro` エンドポイントは以前、エンドユーザーがメールまたは SMS で受け取ったワンタイムパスワード (OTP) を、<Tooltip tip="ID トークン: リソースへのアクセスではなく、クライアント自体を対象とした認証情報。" cta="用語集を見る" href="/docs/ja-jp/glossary?term=ID+token">ID トークン</Tooltip>と <Tooltip tip="アクセストークン: API へのアクセスに使用される、opaque 文字列または JWT 形式の認可資格情報。" cta="用語集を見る" href="/docs/ja-jp/glossary?term=access+token">アクセストークン</Tooltip>に交換するために使用されていました。Auth0 では、このユースケースで `/oauth/ro` に代わる新しい API を実装しており、新しいエンドポイントへの移行を推奨しています。

<div id="features-affected">
  ## 影響を受ける機能
</div>

この変更は、リソース所有者<Tooltip tip="パスワードレス: 第1の認証要素としてパスワードに依存しない認証形式。" cta="用語集を見る" href="/docs/ja-jp/glossary?term=passwordless">パスワードレス</Tooltip>資格情報交換を使用し、Auth0 のライブラリや SDK を使わずに `/oauth/ro` を直接呼び出している場合に影響します。

<Callout icon="file-lines" color="#0EA5E9" iconType="regular">
  ユーザーの `/oauth/ro` ベースのアクセストークンの有効期限が切れると、Auth0 は再認証を強制します (強制ログアウトが必要です) 。これは、`/oauth/ro` のリフレッシュトークンを使って新しいアクセストークンを取得するために `/oauth/token` を呼び出すことができないためです。現在ログインしているすべてのユーザーは、`/oauth/ro` から `/oauth/token` への移行時に再度ログインする必要があります。
</Callout>

<div id="actions">
  ## Actions
</div>

<div id="request-changes">
  ### リクエストの変更
</div>

以前は、`/oauth/ro` へのリクエストのペイロードは次のようになっていました。

```json lines theme={null}
{
  "grant_type": "password",
  "client_id": "123",
  "username": "alice",
  "password": "A3ddj3w", 
  "connection": "my-database-connection",
  "scope": "openid email favorite_color offline_access",
  "device": "my-device-name"
}
```

新しい実装における変更点は次のとおりです。

* token exchange を実行するエンドポイントは `/oauth/token` になりました。
* 特定の接続 (またはレルム) のユーザーを認証するために、Auth0 独自のグラントタイプが使用されます。
* Auth0 は標準の OIDC スコープに加えて、カスタム API で定義したスコープもサポートしています。
* 上記の `favorite_color` のように、これらのカテゴリのいずれにも当てはまらない scope は、無効になりました。
* `device` パラメーターは削除されました。
* `audience` パラメーターは省略可能です。

`/oauth/token` へのリクエストのペイロードの例を次に示します。

export const codeExample = `{
  "grant_type" : "http://auth0.com/oauth/grant-type/passwordless/otp",
  "client_id": "{yourClientId}",
  "client_secret": "{yourClientSecret}", // ウェブアプリのみ。Native アプリにはクライアントシークレットはありません
  "username": "{userEmailAddress}", // または "{userPhoneNumber}"
  "otp": "CODE",
  "realm": "email", // または "sms" 
  "audience" : "{yourApiIdentifier}", // 特定の API のアクセストークンが必要な場合
  "scopes": "openid profile email" // 必要なスコープを指定
}`;

<AuthCodeBlock children={codeExample} language="json" />

* グラントタイプは、ここでは `http://auth0.com/oauth/grant-type/passwordless/otp` として指定します。
* パラメーター `client_id` と `username` は変わりません。
* `client_secret` は、<Tooltip tip="Confidential Client: 信頼できるバックエンドサーバーを使用して資格情報を安全に保持できるクライアント（アプリケーション）。たとえば、安全なバックエンドを備えた Web アプリケーションや machine-to-machine（M2M）アプリケーションが該当します。" cta="用語集を見る" href="/docs/ja-jp/glossary?term=confidential+clients">機密クライアント</Tooltip> (例: regular web app) の場合に指定する必要があります。
* ワンタイムパスワードは、`password` パラメーターではなく `otp` パラメーターで送信する必要があります。
* `realm` は接続を識別するために使用され、以前の呼び出しで使われていた `connection` パラメーターの代わりになります。
* `scope` パラメーターはほぼ同じですが、OIDC 以外の値は受け付けません。
* `audience` パラメーターを追加して、トークンの対象となる API の <Tooltip tip="Audience: 発行されたトークンの audience の一意の識別子。トークンでは aud という名前で、その値には ID トークン の場合はアプリケーション（Client ID）、Access Token の場合は API（API Identifier）の ID が含まれます。" cta="用語集を見る" href="/docs/ja-jp/glossary?term=audience">audience</Tooltip> を指定できます。

<div id="response-changes">
  ### レスポンスの変更
</div>

`/oauth/ro` からのレスポンスは、次のような形式でした。

```json lines theme={null}
{
  "access_token": "SlAV32hkKG",
  "token_type": "Bearer",
  "refresh_token": "8xLOxBtZp8",
  "expires_in": 3600,
  "id_token": "eyJ..."
}
```

* 返されたアクセストークンは、`/userinfo` エンドポイントを呼び出すために有効です (`audience` パラメーターで指定された API が、<Tooltip tip="署名アルゴリズム: トークンが改ざんされていないことを保証するために、トークンにデジタル署名する際に使用されるアルゴリズム。" cta="用語集を見る" href="/docs/ja-jp/glossary?term=signing+algorithm">署名アルゴリズム</Tooltip>として RS256 を使用している場合) 。また、指定されていればカスタム API に対しても有効です。
* <Tooltip tip="パブリッククライアント: 資格情報を安全に保持できないクライアント（アプリケーション）。例としては、ネイティブのデスクトップまたはモバイルのアプリケーション、および JavaScript ベースのクライアントサイドの Web アプリケーション（シングルページアプリケーション（SPA）など）が含まれます。" cta="用語集を見る" href="/docs/ja-jp/glossary?term=public+client">パブリッククライアント</Tooltip>から要求された場合、ID トークンは強制的に RS256 で署名されます。
* `offline_access` スコープが付与され、API で **オフラインアクセスの許可** が設定されている場合にのみ、<Tooltip tip="リフレッシュトークン: ユーザーに再度ログインを求めることなく、新しい Access Token を取得するために使用されるトークン。" cta="用語集を見る" href="/docs/ja-jp/glossary?term=refresh+token">リフレッシュトークン</Tooltip>が返されます。

以下は、`/oauth/token` から返される OIDC 準拠レスポンスの例です。

```json lines theme={null}
{
  "access_token": "eyJ...",
  "token_type": "Bearer",
  "refresh_token": "8xLOxBtZp8",
  "expires_in": 3600,
  "id_token": "eyJ..."
}
```

<div id="code-changes-when-using-the-sdks">
  ### SDK を使用する場合のコード変更
</div>

アプリケーションで Android または iOS 向けの Auth0 Native library を使用している場合は、組み込んでいる library のバージョンが、少なくとも以下に記載の最小バージョン以上であることを確認してください。また、library の設定時には、`OIDC Conformant` flag を `true` に設定してください。

| ライブラリ        | 最小バージョン |
| ------------ | ------- |
| Android SDK  | 1.2     |
| Lock Android | 2.17    |
| Swift SDK    | 1.20.0  |
| Lock iOS     | 2.14.0  |

<div id="verify-migration">
  ### 移行の確認
</div>

1. 非推奨のエンドポイントを使用しているかどうかを確認するには、[テナントログ](https://manage.auth0.com/#/logs)を確認し、**非推奨通知**で絞り込んだうえで、`oauth/ro` **passwordless: This feature is being deprecated** と表示されるログを探します。次のクエリを使って、直接検索することもできます: `type:depnote AND description:*passwordless*`。
2. コードベースの移行を終え、アプリがそのエンドポイントを呼び出していないことを確認したら、[Auth0 Dashboard](https://manage.auth0.com/#/tenant/advanced)の **Tenant Settings > Advanced** に移動します。
3. **Migrations** までスクロールし、**レガシー** `/oauth/ro` **エンドポイント** をオフにします。このスイッチをオフにすると、テナント内でその非推奨エンドポイントが無効になり、使用できなくなります。

このスイッチをオフにした結果、ログイン失敗が発生する場合は、アプリケーションからレガシーコードをまだ完全に取り除けていないことを示しています。

本番環境での移行が正常に完了したら、このスイッチはオフにしてそのまま維持し、非推奨機能が以後使われないようにしてください。

<div id="learn-more">
  ## 詳しくはこちら
</div>

* [リソース所有者パスワードフローの移行](/docs/ja-jp/troubleshoot/product-lifecycle/past-migrations/migration-oauthro-oauthtoken)
