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

> アプリケーションで Native to Web SSO を使用するための設定方法について説明します。

# Native to Web SSO を設定して実装する

export const AuthCodeGroup = ({children, dropdown}) => {
  const [processedChildren, setProcessedChildren] = useState(children);
  useEffect(() => {
    let unsubscribe = null;
    function init() {
      unsubscribe = window.autorun(() => {
        const processChildren = node => {
          if (typeof node === "string") {
            let processedNode = node;
            for (const [key, value] of window.rootStore.variableStore.values.entries()) {
              const escapedKey = key.replaceAll(/[.*+?^${}()|[\]\\]/g, (String.raw)`\$&`);
              processedNode = processedNode.replaceAll(new RegExp(escapedKey, "g"), value);
            }
            return processedNode;
          } else if (Array.isArray(node)) {
            return node.map(processChildren);
          } else if (node && node.props && node.props.children) {
            return {
              ...node,
              props: {
                ...node.props,
                children: processChildren(node.props.children)
              }
            };
          }
          return node;
        };
        setProcessedChildren(processChildren(children));
      });
    }
    if (window.rootStore) {
      init();
    } else {
      window.addEventListener("adu:storeReady", init);
    }
    return () => {
      window.removeEventListener("adu:storeReady", init);
      unsubscribe?.();
    };
  }, [children]);
  return <CodeGroup dropdown={dropdown}>{processedChildren}</CodeGroup>;
};

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) + "*****マスク済み*****";
          }
          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>;
};

<div id="configure-native-to-web-sso">
  ## Native to Web SSO を設定する
</div>

Native to Web <Tooltip tip="シングルサインオン（SSO）：ユーザーが1つのアプリケーションにログインすると、他のアプリケーションにも自動的にログインできるようにするサービスです。" cta="用語集を表示" href="/ja/docs/glossary?term=Single+Sign-On">シングルサインオン</Tooltip> (SSO) を利用するには、Auth0 の <Tooltip tip="Management API: お客様が管理タスクを実行するための製品です。" cta="用語集を表示" href="/ja/docs/glossary?term=Management+API">Management API</Tooltip> を使用してセッションを作成および管理するように、ネイティブアプリと Web アプリ (Single Page App または Regular Web App) を設定します。

Management API または Auth0 CLI を使用するには、[アクセストークン](/ja/docs/secure/tokens/access-tokens/management-api-access-tokens) が必要です。

Native to Web SSO を設定するには、session\_transfer\_tokens を作成および管理し、ネイティブアプリケーションと Web アプリケーションを設定する必要があります。

<Callout icon="file-lines" color="#0EA5E9" iconType="regular">
  Native to Web SSO は、次の SDK をサポートしています: [Auth0 Android SDK](https://github.com/auth0/auth0.android/blob/main/EXAMPLES.md#native-to-web-sso-login-ea)、[Auth0 Swift SDK](https://github.com/auth0/Auth0.swift/blob/master/EXAMPLES.md#sso-credentials-ea)、および [Auth0 React Native SDK](https://github.com/auth0/react-native-auth0/blob/master/EXAMPLES.md#native-to-web-sso-early-access)。

  Native to Web SSO は、次のツールでサポートされています: [Auth0 Deploy CLI](/ja/docs/deploy-monitor/deploy-cli-tool)、[Auth0 Terraform Provider](/ja/docs/deploy-monitor/auth0-terraform-provider)、および [Auth0 CLI](https://auth0.github.io/auth0-cli/)。

  Native to Web SSO は、[Resource Owner Password Flow](/ja/docs/secure/multi-factor-authentication/authenticate-using-ropg-flow-with-mfa) や [Authorization Code Flow with Proof Key for Code Exchange](/ja/docs/get-started/authentication-and-authorization-flow/authorization-code-flow-with-pkce) など、リフレッシュトークンを返すすべての認証フローをサポートしています。
</Callout>

<div id="create-and-manage-session-transfer-tokens">
  ### セッション転送トークン の作成と管理
</div>

最初の Management API 呼び出しでは、ネイティブアプリケーションと Web アプリケーションで次のことが可能になります。

* `session_transfer_tokens` の作成と管理
* Cookie または URL パラメーターを使用して Web ブラウザーでセッションを作成
* IP アドレスまたは ASN を使用して、セッションをユーザーのデバイスに関連付ける

既存のアプリケーションの場合は、[Update a Client](https://auth0.com/docs/api/management/v2/clients/patch-clients-by-id) エンドポイントに対して `PATCH` 呼び出しを行います。新しいアプリケーションを作成するには、[Create a Client](https://auth0.com/docs/api/management/v2/clients/post-clients) エンドポイントに対して `POST` 呼び出しを行います。

```json lines theme={null}
{
  "session_transfer": {
    "can_create_session_transfer_token": false,
    "allowed_authentication_methods": ["cookie", "query"],
    "enforce_device_binding": "ip", // "none" や "asn" も指定可能,
    "allow_refresh_token": false,
    "enforce_cascade_revocation": true,
    "enforce_online_refresh_tokens": true
  }
}
```

<div id="configure-native-applications">
  ### ネイティブアプリケーションを設定する
</div>

ユーザーが認証されると、Auth0 は [アクセストークン](/ja/docs/secure/tokens/access-tokens)、[IDトークン](/ja/docs/secure/tokens/id-tokens)、および (必要に応じて) [リフレッシュトークン](/ja/docs/secure/tokens/refresh-tokens) を返します。

ネイティブアプリケーションを設定して、<Tooltip tip="Refresh Token: ユーザーに再度ログインを要求せずに、新しいアクセストークンを取得するために使用するトークン。" cta="用語集を見る" href="/ja/docs/glossary?term=refresh+token">リフレッシュトークン</Tooltip>をセッション転送トークンと交換できます。Web アプリケーションが Cookie の挿入をサポートしていない場合は、ネイティブアプリケーションで Web アプリケーションの **Login URI** も設定し、セッション転送トークン を URI パラメーターとして渡せるようにする必要があります。

* <Tooltip tip="Auth0 Dashboard: サービスを設定するための Auth0 の主要プロダクト。" cta="用語集を見る" href="/ja/docs/glossary?term=Auth0+Dashboard">Auth0 Dashboard</Tooltip> を使用してネイティブアプリケーションを更新します。

  1. [Dashboard > Applications](https://manage.auth0.com/dashboard/#/applications) に移動します。
  2. アプリケーションを選択するか、[アプリケーションを作成](/ja/docs/get-started/auth0-overview/create-applications#create-applications)します。
  3. **Settings** タブを選択します。
  4. **Session Transfer** で **Allow Native to Web SSO** を有効にします。
  5. **Require Cascade Revocation** を選択して、Web アプリケーションのセッションと関連トークンを自動的に失効させます。
  6. **Save** を選択してアプリケーションを更新します。

<Frame>
  <img src="https://mintcdn.com/translations/S4csL9vq6QUX5-Rr/docs/images/sessions/session-transfer-native-app.png?fit=max&auto=format&n=S4csL9vq6QUX5-Rr&q=85&s=8cf5f51b19b9fae575f76b3560338ba8" alt="Session Transfer ネイティブアプリケーション" width="1404" height="481" data-path="docs/images/sessions/session-transfer-native-app.png" />
</Frame>

* Management API の <Tooltip tip="Access Token: API へのアクセスに使用される、不透明な文字列または JWT の形式の認可資格情報。" cta="用語集を見る" href="/ja/docs/glossary?term=Access+Token">アクセストークン</Tooltip> を使用して、[Update a Client](https://auth0.com/docs/api/management/v2/clients/patch-clients-by-id) エンドポイントでネイティブアプリケーションを更新します。

export const codeExample1 = `curl --request PATCH \
  --url 'https://{yourDomain}/api/v2/clients/{yourClientId}' \
  --header 'authorization: Bearer {yourMgmtApiAccessToken}' \
  --header 'content-type: application/json' \
  --data '{
  "session_transfer": {
    "can_create_session_transfer_token": true,
    "enforce_cascade_revocation": true
  }
}'`;

<AuthCodeBlock children={codeExample1} language="bash" filename="cURL" />

* [Auth0 CLI](https://auth0.github.io/auth0-cli/auth0_apps_session-transfer_update.html) を使用して、ネイティブアプリケーションを更新します。

export const codeExample2 = `auth0 apps session-transfer update {yourClientId} --can-create-token=true`;

<AuthCodeBlock children={codeExample2} language="sh" />

<div id="configure-web-applications">
  ### Webアプリケーションを設定する
</div>

セッション転送トークン を有効にする前に、追加のパラメーターを処理できるよう、Webアプリケーションの **Application Login URI** を設定しておいてください。URI の詳細については、[Application Settings](/ja/docs/get-started/applications/application-settings#application-uris) を参照してください。

* Auth0 Dashboard を使用して Webアプリケーションを更新します。

  1. [Dashboard > Applications](https://manage.auth0.com/dashboard/#/applications) に移動します。
  2. Webアプリケーションを選択するか、新規作成します。
  3. **Settings** タブを選択します。
  4. **Session Transfer** で、**Native to Web SSO Methods** を有効にします。
  5. **Cookie Authentication** と **Query Authentication** を選択します。
  6. **Device Binding Method** を有効にし、**None**、**ASN Binding**、または **IP Address Binding** のいずれかを選択します。
  7. セッショントランスファー後に新しいリフレッシュトークンを発行するには、**Allow Refresh Token Requests** を有効にします。
  8. **Use online refresh tokens** を選択します。
  9. **Save** を選択して Webアプリケーションを更新します。

<Frame>
  <img src="https://mintcdn.com/translations/S4csL9vq6QUX5-Rr/docs/images/sessions/session-transfer-web-application.png?fit=max&auto=format&n=S4csL9vq6QUX5-Rr&q=85&s=a6457fed99af7a46292cc373dad463a1" alt="Session Transfer Web application" width="1404" height="944" data-path="docs/images/sessions/session-transfer-web-application.png" />
</Frame>

* Management API アクセストークンを使用して、[Update a Client](https://auth0.com/docs/api/management/v2/clients/patch-clients-by-id) エンドポイントで Webアプリケーションを更新します。

export const codeExample3 = `curl --request PATCH \
  --url '{yourDomain}/api/v2/clients//{yourClientId}' \
  --header 'authorization: Bearer {yourMgmtApiAccessToken}' \
  --header 'content-type: application/json' \
  --data '{
  "session_transfer": {
    "allowed_authentication_methods": ["cookie", "query"],
    "enforce_device_binding": "ip", // "none" または "asn" も使用可能
    "allow_refresh_token": false,
    "enforce_online_refresh_tokens": true
  }
}'`;

<AuthCodeBlock children={codeExample3} language="bash" filename="cURL" />

* [Auth0 CLI](https://auth0.github.io/auth0-cli/auth0_apps_session-transfer_update.html) を使用して、Web アプリケーションを更新します。

export const codeExample4 = `auth0 apps session-transfer update {yourClientId}  --allowed-auth-methods=cookie,query --enforce-device-binding=ip`;

<AuthCodeBlock children={codeExample4} language="sh" />

<div id="implement-native-to-web-sso">
  ## Native to Web SSO を実装する
</div>

Native to Web Single SSO では、認証済みのユーザーをネイティブアプリケーションから Web アプリケーションへシームレスに移行させることができます。

これを実現するには、ネイティブアプリケーションでリフレッシュトークンをセッション転送トークン に交換し、その セッション転送トークン を URL または cookie 経由で Web アプリケーションに送信して、セッションを認可する必要があります。

<Callout icon="file-lines" color="#0EA5E9" iconType="regular">
  * クライアントで `allow_refresh_token` が無効になっている状態でアプリケーションが `offline_access` を要求しても、Auth0 は `refresh_token` を発行しませんが、認証自体は引き続き機能します。

  * リフレッシュトークンローテーションが有効な場合、Auth0 はトークン交換の呼び出しで新しい `refresh_token` を返します。リフレッシュトークンの交換は、コードで Web アプリケーションを開く直前に行う必要があります。
</Callout>

<div id="in-your-native-application">
  ### ネイティブアプリケーションで
</div>

<div id="step-1-exchanging-a-refresh-token-for-a-session-transfer-token">
  #### ステップ 1: リフレッシュトークンをセッション転送トークンと交換する
</div>

ネイティブアプリケーションで [/token](https://auth0.com/docs/api/authentication/authorization-code-flow-with-pkce/get-token-pkce) エンドポイントを使用して、リフレッシュトークンをセッション転送トークンと交換します。

* Swift、Android、または React Native SDK を使用してリフレッシュトークンをセッション転送トークンと交換する:

<Tabs>
  <Tab title="Swift SDK">
    ```swift lines theme={null}
    credentialsManager.ssoCredentials { result in
        switch result {
        case .success(let ssoCredentials):
            print("Obtained SSO credentials: \(ssoCredentials)")
        case .failure(let error):
            print("Failed with: \(error)")
        }
    }

    // または async/await を使用

    do {
        let ssoCredentials = try await credentialsManager.ssoCredentials()
        print("Obtained SSO credentials: \(ssoCredentials)")
    } catch {
        print("Failed with: \(error)")
    }
    ```
  </Tab>

  <Tab title="Android SDK">
    ```kotlin lines theme={null}
    secureCredentialsManager.getSsoCredentials(
        mapOf(),  // オプション パラメーター
        object : Callback<SSOCredentials, CredentialsManagerException> {
            override fun onSuccess(result: SSOCredentials) {
                // result.sessionTransferToken を使用して
                // アプリ内の Web セッションでユーザーを認証します
            }

            override fun onFailure(error: CredentialsManagerException) {
                // エラーを処理します
            }
        }
    )
    ```
  </Tab>

  <Tab title="React Native SDK">
    ```typescript lines theme={null}
    // Hooks を使用
    import { useAuth0 } from 'react-native-auth0';

    function MyComponent() {
      const { getSSOCredentials } = useAuth0();

      const openWebApp = async () => {
        try {
          const ssoCredentials = await getSSOCredentials();
          // ssoCredentials.sessionTransferToken を使用して
          // アプリ内の Web セッションでユーザーを認証します
          console.log('Session Transfer Token:', ssoCredentials.sessionTransferToken);
        } catch (error) {
          console.error('Failed to get SSO credentials:', error);
        }
      };
    }

    // Auth0 クラスを使用
    import Auth0 from 'react-native-auth0';

    const auth0 = new Auth0({
      domain: '{yourDomain}',
      clientId: '{yourClientId}',
    });

    const ssoCredentials = await auth0.credentialsManager.getSSOCredentials();
    console.log('Session Transfer Token:', ssoCredentials.sessionTransferToken);
    ```
  </Tab>
</Tabs>

* HTTP を使用してリフレッシュトークンをセッション転送トークンと交換する:

export const codeExample5 = `curl -X POST https://{yourDomain}/oauth/token \
  -H 'Content-type: application/json' \
  -d '{"grant_type":"refresh_token", 
    "client_id":{yourClientId}",
    "refresh_token":"YOUR_REFRESH_TOKEN",
    "audience":"urn:YOUR_AUTH0_TENANT_DOMAIN:session_transfer"}'`;

<AuthCodeBlock children={codeExample5} language="bash" filename="cURL" />

<Callout icon="file-lines" color="#0EA5E9" iconType="regular">
  これらのサンプルでは、可変の値にプレースホルダーを使用しています。プレースホルダーは、Auth0 のドメイン、client\_id、既存の refresh\_token に置き換えてください。
</Callout>

Auth0 テナントは、1 回限り使用でき、有効期間が短い (1 分) session\_transfer\_token を返します。

```json lines theme={null}
{
    "access_token": "{session_transfer_token}",
    "issued_token_type": "urn:auth0:params:oauth:token-type:session_transfer_token",
    "token_type": "N_A",
    "expires_in": 60
}
```

<Callout icon="file-lines" color="#0EA5E9" iconType="regular">
  リフレッシュトークンのローテーションが有効な場合、この交換ではリフレッシュトークンも返されます。

  認証時にIDトークンを要求していた場合、この呼び出しでもIDトークンが返されます。
</Callout>

<div id="step-2-send-the-session-transfer-token-through-a-url-or-cookie">
  #### ステップ 2: URL または Cookie でセッション転送トークン を送信する
</div>

設定されている `allowed_authentication_methods` に応じて、`session_transfer_token` を Web アプリケーションに送信する方法は 2 つあります。

<div id="option-1-send-the-session_transfer_token-as-a-cookie">
  ##### オプション 1: session\_transfer\_token をクッキーとして送信する
</div>

WebView またはブラウザーを使用する Web アプリケーションがクッキーの挿入をサポートしている場合は、ネイティブアプリケーションを次のように設定できます。

* session\_transfer\_token をクッキーに追加します。
* WebView またはブラウザーを使用して Web アプリケーションを開きます。
* Web アプリケーションで、Auth0 テナントまたは <Tooltip tip="Custom Domain: 専用名（バニティ名）を持つサードパーティドメイン。" cta="用語集を表示" href="/ja/docs/glossary?term=Custom+Domain">Custom Domain</Tooltip> にログインします。`session_transfer_token` がクッキーに含まれているため、ユーザーに第 1 認証要素での認証は求められません。

export const codeExample6 = `curl --cookie auth0_session_transfer_token=YOUR_SESSION_TRANSFER_TOKEN
      https://{yourDomain}/authorize?{authorize_params}`;

<AuthCodeBlock children={codeExample6} language="bash" filename="cURL" />

<div id="option-2-send-the-session_transfer_token-as-a-url-parameter">
  ##### オプション 2: `session_transfer_token` を URL パラメーターとして送信する
</div>

Web アプリケーションが cookie インジェクションをサポートしていない場合は、URL パラメーターを使用するようにネイティブアプリケーションを設定し、次のことを行えます。

* `session_transfer_token` を URL パラメーターとして追加します。
* WebView またはブラウザーで Web アプリケーションを開きます。
* [`/authorize`](https://auth0.com/docs/api/authentication/authorization-code-flow/authorize-application) エンドポイントに `session_transfer_token` を URL パラメーターとして付加して、Web アプリケーションにログインします。`session_transfer_token` は有効で信頼できるため、Auth0 テナントは第 1 認証要素を要求せずにユーザーを認証します。

<AuthCodeGroup>
  ```bash cURL lines theme={null}
  curl --request GET \
    --url 'https://your_web_app_login_url/?session_transfer_token=YOUR_SESSION_TRANSFER_TOKEN'
  ```

  ```csharp C# lines theme={null}
  var client = new RestClient("https://your_web_app_login_url/?session_transfer_token=YOUR_SESSION_TRANSFER_TOKEN");
  var request = new RestRequest(Method.GET);
  IRestResponse response = client.Execute(request);
  ```

  ```go Go lines theme={null}
  package main

  import (
  	"fmt"
  	"net/http"
  	"io/ioutil"
  )

  func main() {

  	url := "https://your_web_app_login_url/?session_transfer_token=YOUR_SESSION_TRANSFER_TOKEN"

  	req, _ := http.NewRequest("GET", url, nil)

  	res, _ := http.DefaultClient.Do(req)

  	defer res.Body.Close()
  	body, _ := ioutil.ReadAll(res.Body)

  	fmt.Println(res)
  	fmt.Println(string(body))

  }
  ```

  ```java Java lines theme={null}
  HttpResponse<String> response = Unirest.get("https://your_web_app_login_url/?session_transfer_token=YOUR_SESSION_TRANSFER_TOKEN")
    .asString();
  ```

  ```javascript Node.JS lines theme={null}
  var axios = require("axios").default;

  var options = {
    method: 'GET',
    url: 'https://your_web_app_login_url/',
    params: {session_transfer_token: 'YOUR_SESSION_TRANSFER_TOKEN'}
  };

  axios.request(options).then(function (response) {
    console.log(response.data);
  }).catch(function (error) {
    console.error(error);
  });
  ```

  ```php PHP lines theme={null}
  $curl = curl_init();

  curl_setopt_array($curl, [
    CURLOPT_URL => "https://your_web_app_login_url/?session_transfer_token=YOUR_SESSION_TRANSFER_TOKEN",
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_ENCODING => "",
    CURLOPT_MAXREDIRS => 10,
    CURLOPT_TIMEOUT => 30,
    CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
    CURLOPT_CUSTOMREQUEST => "GET",
  ]);

  $response = curl_exec($curl);
  $err = curl_error($curl);

  curl_close($curl);

  if ($err) {
    echo "cURL Error #:" . $err;
  } else {
    echo $response;
  }
  ```

  ```python Python lines theme={null}
  import http.client

  conn = http.client.HTTPSConnection("your_web_app_login_url")

  conn.request("GET", "/?session_transfer_token=YOUR_SESSION_TRANSFER_TOKEN")

  res = conn.getresponse()
  data = res.read()

  print(data.decode("utf-8"))
  ```

  ```ruby Ruby lines theme={null}
  require 'uri'
  require 'net/http'
  require 'openssl'

  url = URI("https://your_web_app_login_url/?session_transfer_token=YOUR_SESSION_TRANSFER_TOKEN")

  http = Net::HTTP.new(url.host, url.port)
  http.use_ssl = true
  http.verify_mode = OpenSSL::SSL::VERIFY_NONE

  request = Net::HTTP::Get.new(url)

  response = http.request(request)
  puts response.read_body
  ```
</AuthCodeGroup>

<div id="in-your-web-application">
  ### ウェブアプリケーションで
</div>

<Callout icon="file-lines" color="#0EA5E9" iconType="regular">
  セッション転送トークン が Cookie として送信される場合、ブラウザーが `/authorize` エンドポイントへのリクエストでその Cookie を送信するため、追加の設定は不要です。
</Callout>

URL パラメーターを使用して、ウェブアプリケーションに Native to Web Web Single SSO を実装するには、次の手順に従います。

<div id="option-1-add-the-session-transfer-token-in-your-web-application-request">
  #### オプション 1: Web アプリケーションのリクエストにセッション転送トークン を追加する
</div>

アプリケーションのログイン URL から、`session_transfer_token` を URL パラメーターとして送信して `/authorize` エンドポイントにリダイレクトします。

<AuthCodeGroup>
  ```bash cURL theme={null}
  curl --request GET \
    --url 'https://{yourDomain}/authorize?session_transfer_token=YOUR_SESSION_TRANSFER_TOKEN&client_ID={yourClientId}&redirect_uri=YOUR_REDIRECT_URI&response_type=code'
  ```

  ```csharp C# theme={null}
  var client = new RestClient("https://{yourDomain}/authorize?session_transfer_token=YOUR_SESSION_TRANSFER_TOKEN&client_ID={yourClientId}&redirect_uri=YOUR_REDIRECT_URI&response_type=code");
  var request = new RestRequest(Method.GET);
  IRestResponse response = client.Execute(request);
  ```

  ```go Go theme={null}
  package main

  import (
  	"fmt"
  	"net/http"
  	"io/ioutil"
  )

  func main() {

  	url := "https://{yourDomain}/authorize?session_transfer_token=YOUR_SESSION_TRANSFER_TOKEN&client_ID={yourClientId}&redirect_uri=YOUR_REDIRECT_URI&response_type=code"

  	req, _ := http.NewRequest("GET", url, nil)

  	res, _ := http.DefaultClient.Do(req)

  	defer res.Body.Close()
  	body, _ := ioutil.ReadAll(res.Body)

  	fmt.Println(res)
  	fmt.Println(string(body))

  }
  ```

  ```java Java theme={null}
  HttpResponse<String> response = Unirest.get("https://{yourDomain}/authorize?session_transfer_token=YOUR_SESSION_TRANSFER_TOKEN&client_ID={yourClientId}&redirect_uri=YOUR_REDIRECT_URI&response_type=code")
    .asString();
  ```

  ```javascript Node.JS theme={null}
  var axios = require("axios").default;

  var options = {
    method: 'GET',
    url: 'https://{yourDomain}/authorize',
    params: {
      session_transfer_token: 'YOUR_SESSION_TRANSFER_TOKEN',
      client_ID: '{yourClientId}',
      redirect_uri: 'YOUR_REDIRECT_URI',
      response_type: 'code'
    }
  };

  axios.request(options).then(function (response) {
    console.log(response.data);
  }).catch(function (error) {
    console.error(error);
  });
  ```

  ```php PHP theme={null}
  $curl = curl_init();

  curl_setopt_array($curl, [
    CURLOPT_URL => "https://{yourDomain}/authorize?session_transfer_token=YOUR_SESSION_TRANSFER_TOKEN&client_ID={yourClientId}&redirect_uri=YOUR_REDIRECT_URI&response_type=code",
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_ENCODING => "",
    CURLOPT_MAXREDIRS => 10,
    CURLOPT_TIMEOUT => 30,
    CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
    CURLOPT_CUSTOMREQUEST => "GET",
  ]);

  $response = curl_exec($curl);
  $err = curl_error($curl);

  curl_close($curl);

  if ($err) {
    echo "cURL Error #:" . $err;
  } else {
    echo $response;
  }
  ```

  ```python Python theme={null}
  import http.client

  conn = http.client.HTTPSConnection("")

  conn.request("GET", "/{yourDomain}/authorize?session_transfer_token=YOUR_SESSION_TRANSFER_TOKEN&client_ID={yourClientId}&redirect_uri=YOUR_REDIRECT_URI&response_type=code")

  res = conn.getresponse()
  data = res.read()

  print(data.decode("utf-8"))
  ```
</AuthCodeGroup>

<div id="option-2-add-the-session-transfer-token-to-web-applications-using-auth0-sdks">
  #### オプション 2: Auth0 SDK を使用する Web アプリケーションにセッション転送トークン を追加する
</div>

Auth0 SDK は Native to Web SSO を自動ではサポートしていないため、`/authorize` エンドポイントへのリクエストに `session_transfer_token` は含まれません。

以下は、Auth0 SDK を使用する Web アプリケーションで、`/authorize` エンドポイントへのリクエストに `session_transfer_token` を追加してリダイレクトする例です:

<div id="node-expressjs">
  ##### Node (Express.js)
</div>

Web アプリケーションで [Express.js](https://expressjs.com/) または [Auth0 Express SDK](https://github.com/auth0/express-openid-connect) を使用している場合は、以下のコードを使って `session_transfer_token` をサポートするミドルウェアを追加できます。

```javascript javascript lines theme={null}
const baseConfig = {
  authRequired: false,
  auth0Logout: true
};

// session_transfer_tokenを自動検出するためにミドルウェアを拡張する
app.use((req, res, next) => {
  const { session_transfer_token } = req.query;

  // stateの漏洩を防ぐため、リクエストごとに新しい設定を作成する
  const config = { ...baseConfig };

  if (session_transfer_token) {
    config.authorizationParams = {
      session_transfer_token,
    };
  }

  auth(config)(req, res, next);
});
```

<div id="auth0-spa-sdk-auth0auth0-spa-js">
  ##### Auth0 SPA SDK (@auth0/auth0-spa-js)
</div>

Web アプリケーションで [Auth0 SPA SDK](https://github.com/auth0/auth0-spa-js) を使用している場合は、`authorizationParams` 経由で `session_transfer_token` を `loginWithRedirect()` に渡せます。

```typescript typescript lines theme={null}
import { Auth0Client } from '@auth0/auth0-spa-js';

const auth0 = new Auth0Client({
  domain: '{yourDomain}',
  clientId: '{yourClientId}',
});

// URLクエリパラメータからsession_transfer_tokenを取得（ネイティブアプリから渡される）
const urlParams = new URLSearchParams(window.location.search);
const sessionTransferToken = urlParams.get('session_transfer_token');

// session_transfer_tokenを使用してloginWithRedirectを呼び出す
if (sessionTransferToken) {
  await auth0.loginWithRedirect({
    authorizationParams: {
      session_transfer_token: sessionTransferToken,
      redirect_uri: window.location.origin,
    },
  });
}
```

<div id="auth0-react-sdk-auth0auth0-react">
  ##### Auth0 React SDK (@auth0/auth0-react)
</div>

Web アプリケーションで [Auth0 React SDK](https://github.com/auth0/auth0-react) を使用している場合は、`useAuth0` フックの `loginWithRedirect` を使って `session_transfer_token` を渡せます。

```typescript typescript lines theme={null}
import { useEffect } from 'react';
import { useAuth0 } from '@auth0/auth0-react';

function App() {
  const { loginWithRedirect, isAuthenticated, isLoading } = useAuth0();

  useEffect(() => {
    if (isLoading || isAuthenticated) return;

    const urlParams = new URLSearchParams(window.location.search);
    const sessionTransferToken = urlParams.get('session_transfer_token');

    if (sessionTransferToken) {
      loginWithRedirect({
        authorizationParams: {
          session_transfer_token: sessionTransferToken,
        },
      });
    }
  }, [loginWithRedirect, isLoading, isAuthenticated]);

  return <div>...</div>;
}
```

<div id="saml-and-ws-federation">
  ##### SAML と WS-Federation
</div>

Web アプリケーションで、サービスプロバイダーとして <Tooltip tip="Security Assertion Markup Language (SAML): パスワードなしで 2 者間の認証情報の交換を可能にする標準化プロトコル。" cta="用語集を表示" href="/ja/docs/glossary?term=SAML">SAML</Tooltip> または <Tooltip tip="Security Assertion Markup Language (SAML): パスワードなしで 2 者間の認証情報の交換を可能にする標準化プロトコル。" cta="用語集を表示" href="/ja/docs/glossary?term=WS-Fed">WS-Fed</Tooltip> を使用し、Auth0 を <Tooltip tip="Web Service Federation (WS-Fed): ドメインをまたいでユーザー ID を管理するためのプロトコル。" cta="用語集を表示" href="/ja/docs/glossary?term=IdP">IdP</Tooltip> として使用している場合は、`session_transfer_token` を URL パラメーターとして Auth0 の `/authorize` エンドポイントに送信できます。`redirect_uri` は、SAML または WS-Fed のサインイン URL です。

<AuthCodeGroup>
  ```bash cURL theme={null}
  curl --request GET \
    --url 'https://{yourDomain}/samlp//{yourClientId}?session_transfer_token=YOUR_SESSION_TRANSFER_TOKEN' \
    --header 'cookie: session_transfer_token=YOUR_SESSION_TRANSFER_TOKEN' \
    --cookie session_transfer_token=YOUR_SESSION_TRANSFER_TOKEN
  ```

  ```csharp C# theme={null}
  var client = new RestClient("https://{yourDomain}/samlp//{yourClientId}?session_transfer_token=YOUR_SESSION_TRANSFER_TOKEN");
  var request = new RestRequest(Method.GET);
  request.AddHeader("cookie", "session_transfer_token=YOUR_SESSION_TRANSFER_TOKEN");
  IRestResponse response = client.Execute(request);
  ```

  ```go Go theme={null}
  package main

  import (
  	"fmt"
  	"net/http"
  	"io/ioutil"
  )

  func main() {

  	url := "https://{yourDomain}/samlp//{yourClientId}?session_transfer_token=YOUR_SESSION_TRANSFER_TOKEN"

  	req, _ := http.NewRequest("GET", url, nil)

  	req.Header.Add("cookie", "session_transfer_token=YOUR_SESSION_TRANSFER_TOKEN")

  	res, _ := http.DefaultClient.Do(req)

  	defer res.Body.Close()
  	body, _ := ioutil.ReadAll(res.Body)

  	fmt.Println(res)
  	fmt.Println(string(body))
  }
  ```

  ```java Java theme={null}
  HttpResponse response = Unirest.get("https://{yourDomain}/samlp//{yourClientId}?session_transfer_token=YOUR_SESSION_TRANSFER_TOKEN")
    .header("cookie", "session_transfer_token=YOUR_SESSION_TRANSFER_TOKEN")
    .asString();
  ```

  ```javascript Node.JS theme={null}
  var axios = require("axios").default;

  var options = {
    method: 'GET',
    url: 'https://{yourDomain}/samlp//{yourClientId}',
    params: {session_transfer_token: 'YOUR_SESSION_TRANSFER_TOKEN'},
    headers: {cookie: 'session_transfer_token=YOUR_SESSION_TRANSFER_TOKEN'}
  };

  axios.request(options).then(function (response) {
    console.log(response.data);
  }).catch(function (error) {
    console.error(error);
  });
  ```

  ```php PHP theme={null}
  $curl = curl_init();

  curl_setopt_array($curl, [
    CURLOPT_URL => "https://{yourDomain}/samlp//{yourClientId}?session_transfer_token=YOUR_SESSION_TRANSFER_TOKEN",
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_ENCODING => "",
    CURLOPT_MAXREDIRS => 10,
    CURLOPT_TIMEOUT => 30,
    CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
    CURLOPT_CUSTOMREQUEST => "GET",
    CURLOPT_HTTPHEADER => [
      "cookie: session_transfer_token=YOUR_SESSION_TRANSFER_TOKEN"
    ],
  ]);

  $response = curl_exec($curl);
  $err = curl_error($curl);

  curl_close($curl);

  if ($err) {
    echo "cURL Error #:" . $err;
  } else {
    echo $response;
  }
  ```

  ```python Python theme={null}
  import http.client

  conn = http.client.HTTPSConnection("")

  headers = { 'cookie': "session_transfer_token=YOUR_SESSION_TRANSFER_TOKEN" }

  conn.request("GET", "/{yourDomain}/samlp//{yourClientId}?session_transfer_token=YOUR_SESSION_TRANSFER_TOKEN", headers=headers)

  res = conn.getresponse()
  data = res.read()

  print(data.decode("utf-8"))
  ```

  ```ruby Ruby theme={null}
  require 'uri'
  require 'net/http'
  require 'openssl'

  url = URI("https://{yourDomain}/samlp//{yourClientId}?session_transfer_token=YOUR_SESSION_TRANSFER_TOKEN")

  http = Net::HTTP.new(url.host, url.port)
  http.use_ssl = true
  http.verify_mode = OpenSSL::SSL::VERIFY_NONE

  request = Net::HTTP::Get.new(url)
  request["cookie"] = 'session_transfer_token=YOUR_SESSION_TRANSFER_TOKEN'

  response = http.request(request)
  puts response.read_body
  ```
</AuthCodeGroup>

<div id="native-to-web-sso-with-organizations">
  ## 組織を使用した Native to Web SSO
</div>

Native to Web SSO では [組織](/ja/docs/manage-users/organizations) をサポートしています。ネイティブアプリケーションでユーザーが組織を指定して認証されると、セッション転送トークンにはその組織コンテキストが含まれます。

<Callout icon="file-lines" color="#0EA5E9" iconType="regular">
  Native to Web SSO で組織を使用する場合、Web アプリケーションの `/authorize` リクエスト内の `organization` パラメーターは、セッション転送トークンに関連付けられた組織と一致している必要があります。一致しない場合、認証は失敗し、ユーザーは再度ログインを求められます。
</Callout>

Native to Web SSO で組織を使用するには:

1. ネイティブアプリケーションで、組織を指定してユーザーを認証します:

```javascript javascript lines theme={null}
// 組織を使用したネイティブアプリのログイン
await authorize({
  organization: 'org_abc123',
  scope: 'openid profile email offline_access'
});
```

2. Web アプリケーションにリダイレクトする際は、`/authorize` リクエストに同じ組織を含めてください。

```bash bash lines theme={null}
https://{yourDomain}/authorize?
  client_id={yourWebClientId}&
  redirect_uri={yourRedirectUri}&
  response_type=code&
  organization=org_abc123&
  session_transfer_token=YOUR_SESSION_TRANSFER_TOKEN
```

`/authorize` リクエスト内の組織がセッション転送トークン内の組織と一致しない場合、セッション転送トークンは拒否され、ユーザーは再認証のためログインページにリダイレクトされます。イベントの説明 "Single Sign-On failed: Session Transfer Token organization mismatch detected." を含む警告ログが、テナントログに記録されます。

<div id="session-transfer-token-with-actions">
  ## Actions を使用するセッション転送トークン
</div>

[Actions](/ja/docs/customize/actions) で `session_transfer_token` を使用すると、認証後のリスク検知と対応機能を構成し、ユーザー保護を強化できます。

これを可能にするために、post-login の Action オブジェクト **event.session\_transfer\_token** には、一意の `client_id`、`scope`、`ip`、`asn`、`user_agent` などの `request` 情報や、`cityName`、`countryCode` などの `geoip` 情報をはじめとする関連情報が含まれます。詳細については、[Actions Triggers: post-login - Event Object](/ja/docs/customize/actions/explore-triggers/signup-and-login-triggers/login-trigger/post-login-event-object) を参照してください。

以下の Action コードでは、地理位置情報に基づいてトランザクションを動的に拒否できます。

```javascript javascript lines theme={null}
/**
* PostLoginフローの実行中に呼び出されるハンドラー。
*
* @param {Event} event - ユーザーおよびログイン時のコンテキストに関する詳細情報。
* @param {PostLoginAPI} api - ログインの動作を変更するために使用できるメソッドを持つインターフェース。
*/
exports.onExecutePostLogin = async (event, api) => {
   if(
     event.session_transfer_token &&
     event.session_transfer_token.request.geoip.countryCode !== event.request.geoip.countryCode
     ) {
     api.access.deny("Network mismatch detected")
   }
};
```

<div id="access-parent-refresh-token-metadata">
  ### 親リフレッシュトークンのメタデータへのアクセス
</div>

Native to Web SSO では、SSO フローの開始に使用された親リフレッシュトークンのメタデータにアクセスできます。これにより、ネイティブアプリケーションで収集したコンテキスト情報 (デバイスの完全性、リスクシグナル、カスタムコンテキストなど) を、`session_transfer_token` から作成された Web セッションに引き継ぐことができます。

Auth0 は、この情報を Post Login Actions の `event.session.session_transfer.parent_refresh_token.metadata` オブジェクトで公開します。これにより、プラットフォーム間でメタデータを安全かつ標準化された方法で受け渡しできます。

<Callout icon="file-lines" color="#0EA5E9" iconType="regular">
  **使用例:** モバイルアプリでリスクデータ (デバイススコア、位置情報など) を収集し、それをリフレッシュトークンのメタデータに保存します。ネイティブアプリが Native to Web SSO フローを開始すると、そのメタデータは対応する Web セッションで Actions を通じて自動的に利用できるようになります。
</Callout>

以下の Action コードを使用すると、ネイティブアプリケーションから渡されたデバイス信頼メタデータに基づいて、条件付きアクセスロジックを実行できます。

```javascript javascript lines theme={null}
/**
* PostLoginフローの実行中に呼び出されるハンドラー。
*
* @param {Event} event - ユーザーおよびログインコンテキストの詳細。
* @param {PostLoginAPI} api - ログインの動作を変更するために使用できるメソッドのインターフェース。
*/
exports.onExecutePostLogin = async (event, api) => {
  // 親リフレッシュトークン（ネイティブアプリ）からメタデータを取得する
  const parentMetadata = event.session?.session_transfer?.parent_refresh_token?.metadata;

  if (parentMetadata) {
    const deviceTrustLevel = parentMetadata.device_trust;

    if (deviceTrustLevel !== 'high') {
      api.access.deny("Device trust level insufficient.");
    }

    // ネイティブアプリのコンテキストに基づいてclaimsを追加することも可能
    if (parentMetadata.subscription_tier) {
      api.idToken.setCustomClaim('subscription_tier', parentMetadata.subscription_tier);
    }
  }
};
```

<div id="monitoring">
  ## 監視
</div>

Native to Web SSO のアクティビティは、テナントの[ログ](/ja/docs/deploy-monitor/logs)を確認することで監視できます。

<div id="token-exchange-logs">
  ### トークン交換ログ
</div>

* `sertft` : リフレッシュトークン交換の成功。このログは、`audience` フィールドが `"audience":"urn:$auth0Domain:session_transfer"` の場合、Native から Web への SSO 交換に対応するものです
* `fertft`: リフレッシュトークン交換の失敗。このログは、`audience` フィールドが `"audience": "urn:$auth0Domain:session_transfer"` の場合、Native から Web への SSO 交換に対応するものです

<div id="session-transfer-validation-warning-logs">
  ### セッション転送検証の警告ログ
</div>

Auth0 は、`/authorize` リクエスト中にセッション転送トークンの検証が失敗すると、警告ログ (`w`) を出力します。これらのログは、Native to Web SSO の問題のトラブルシューティングに役立ちます。

| イベントの説明                                                                                                                  | 原因                                                                          |
| ------------------------------------------------------------------------------------------------------------------------ | --------------------------------------------------------------------------- |
| `Single Sign-On failed: Session Transfer Token not found or expired. This may indicate token reuse or expiration.`       | セッション転送トークンが見つからない、すでに使用されている、または有効期限が切れています (トークンは 1 回限り有効で、有効期間は 1 分です) 。 |
| `Single Sign-On failed: Session Transfer Token device binding validation failed due to IP/ASN mismatch.`                 | Web リクエストの IP アドレスまたは ASN が、セッション転送トークンに設定されたデバイスバインディングと一致していません。          |
| `Single Sign-On failed: Session Transfer Token organization mismatch detected.`                                          | `/authorize` リクエストの `organization` パラメーターが、セッション転送トークン内の組織と一致していません。        |
| `Single Sign-On failed: Session Transfer Token user mismatch detected.`                                                  | 既存の Auth0 セッションが、セッション転送トークンとは別のユーザーに属しています。                                |
| `Single Sign-On failed: Parent refresh token not found. Session Transfer Token won't be used for session establishment.` | セッション転送トークンの作成に使用された親リフレッシュトークンが失効しているか、削除されています。                           |
