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

# Configure and Implement Native to Web SSO

> Learn how to configure your applications to use Native to Web Single Sign-On.

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) + "*****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>;
};

<Warning>
  Native to Web SSO is currently available in Early Access. To use this feature, you must have an Enterprise plan. By using this feature, you agree to the applicable Free Trial terms in Okta’s [Master Subscription Agreement](https://www.okta.com/legal/?_gl=1*agihqh*_gcl_au*NjM2NjA1MDg4LjE3NTM5ODE4NjY.*_ga*MTgyNDA4MjM2Ny4xNzE1MTAyMjQy*_ga_QKMSDV5369*czE3NTQ0NzQ3NTAkbzM1MyRnMSR0MTc1NDQ3NjU5MCRqNiRsMCRoMA..). To learn more about Auth0's product release cycle, review Product Release Stages.
</Warning>

## Configure Native to Web SSO

To use Native to Web <Tooltip data-tooltip-id="react-containers-DefinitionTooltip-0" href="/docs/ja-jp/glossary?term=single-sign-on" tip="シングルサインオン（SSO）: ユーザーが1つのアプリケーションにログインした後、そのユーザーを他のアプリケーションに自動的にログインさせるサービス。" cta="用語集の表示">Single Sign-On</Tooltip> (SSO), configure your native and web (Single Page App or Regular Web App) to create and manage sessions with the Auth0 <Tooltip data-tooltip-id="react-containers-DefinitionTooltip-0" href="/docs/ja-jp/glossary?term=management-api" tip="Management API: 顧客が管理タスクを実行できるようにするための製品。" cta="用語集の表示">Management API</Tooltip>.

You need an [access token](/docs/ja-jp/secure/tokens/access-tokens/management-api-access-tokens) to use the Management API or Auth0 CLI.

To configure Native to Web SSO, you need to create and manage session\_transfer\_tokens and configure your native and web applications.

<Callout icon="file-lines" color="#0EA5E9" iconType="regular">
  Native to Web SSO supports the following SDKs: [Auth0 Android SDK](https://github.com/auth0/auth0.android/blob/main/EXAMPLES.md#native-to-web-sso-login-ea) and [Auth0 Swift SDK](https://github.com/auth0/Auth0.swift/blob/master/EXAMPLES.md#sso-credentials-ea).

  Native to Web SSO support is available in the following tools: [Auth0 Deploy CLI](https://auth0.com/docs/deploy-monitor/deploy-cli-tool). [Auth0 Terraform Provider](https://auth0.com/docs/deploy-monitor/auth0-terraform-provider) and [Auth0 CLI](https://auth0.github.io/auth0-cli/).

  Native to Web SSO supports any authentication flow that returns a refresh token, such as [Resource Owner Password Flow](/docs/ja-jp/secure/multi-factor-authentication/authenticate-using-ropg-flow-with-mfa) and [Authorization Code Flow with Proof Key for Code Exchange](/docs/ja-jp/get-started/authentication-and-authorization-flow/authorization-code-flow-with-pkce).
</Callout>

### Create and manage Session Transfer Tokens

The first Management API call allows your native and web Applications to:

* Create and manage `session_transfer_tokens`
* Create sessions in a web browser via cookies or a URL parameter
* Bind the session to a user's device through an IP address or ASN

For existing applications, make a `PATCH` call to the [Update a Client](https://auth0.com/docs/api/management/v2/clients/patch-clients-by-id) endpoint. To create a new application, make a `POST` call to the [Create a Client](https://auth0.com/docs/api/management/v2/clients/post-clients) endpoint:

```json lines theme={null}
{
  "session_transfer": {
    "can_create_session_transfer_token": false,
    "allowed_authentication_methods": ["cookie", "query"],
    "enforce_device_binding": "ip", // also "none" or "asn",
    "allow_refresh_token": false,
    "enforce_cascade_revocation": true,
    "enforce_online_refresh_tokens": true
  }
}
```

### Configure native applications

Once a user is authenticated, Auth0 returns an [Access token](/docs/ja-jp/secure/tokens/access-tokens), and [ID token](/docs/ja-jp/secure/tokens/id-tokens), and (optionally) a [Refresh token](/docs/ja-jp/secure/tokens/refresh-tokens).

You can configure your native application to exchange a <Tooltip data-tooltip-id="react-containers-DefinitionTooltip-2" href="/docs/ja-jp/glossary?term=refresh-token" tip="リフレッシュトークン: ユーザーに再度ログインを強いることなく、更新されたアクセストークンを取得するために使用されるトークン。" cta="用語集の表示">refresh token</Tooltip> for a Session Transfer Token. If your web application does not support cookie injection, your native application also needs to configure your web application’s **Login URI** to inject the Session Transfer Token as a URI parameter.

* Update your native application using your Management API <Tooltip data-tooltip-id="react-containers-DefinitionTooltip-3" href="/docs/ja-jp/glossary?term=access-token" tip="アクセストークン: APIへのアクセスに使用される、不透明な文字列またはJWT形式の認可資格情報。" cta="用語集の表示">Access Token</Tooltip> with the [Update a Client](https://auth0.com/docs/api/management/v2/clients/patch-clients-by-id) endpoint:

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_device_binding": "ip"
  }
}'`;

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

* Update your native application using [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 --enforce-device-binding=asn`;

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

### Configure web applications

Before you enable Session Transfer Token, make sure you have configured your web application’s **Application Login URI** to handle extra parameters. To learn more about URIs, read [Application Settings](https://auth0.com/docs/get-started/applications/application-settings#application-uris).

* Update your web application using the Management API Access Token with the [Update a Client](https://auth0.com/docs/api/management/v2/clients/patch-clients-by-id) endpoint:

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"]
  }
}'`;

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

* Update your web application using [Auth0 CLI](https://auth0.github.io/auth0-cli/auth0_apps_session-transfer_update.html):

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

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

## Implement Native to Web SSO

Native to Web Single SSO provides a seamless user experience transitioning authenticated users from your native application to your web application.

To facilitate this, your native application needs to exchange a refresh token for a Session Transfer Token and send the Session Transfer Token, through a URL or cookie, to your web application to authorize the session.

<Callout icon="file-lines" color="#0EA5E9" iconType="regular">
  If `allow_refresh_token` is disabled in the client but the application requests `offline_access`, Auth0 will not issue a `refresh_token` but the authentication will still work.

  If refresh token rotation is enabled, Auth0 returns a new `refresh_token` in the token exchange call. The refresh token exchange should happen immediately before your code opens the web application.
</Callout>

### In your native application

#### Step 1: Exchanging a Refresh Token for a Session Transfer Token

Use the [/token](https://auth0.com/docs/api/authentication/authorization-code-flow-with-pkce/get-token-pkce) endpoint with your native application to exchange the refresh token for a Session Transfer Token.

* Exchange a refresh token for a session transfer token using Swift or Android SDKs:

<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)")
        }
    }

    // Or, using async/await

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

  <Tab title="Android SDK">
    ```swift lines theme={null}
    authentication
    .ssoExchange("refresh_token")
    .start(object : Callback<SSOCredentials, AuthenticationException> {
        override fun onSuccess(result: SSOCredentials) {
            // Use the sessionTransferToken token to authenticate the user in a web session in your app
        }

        override fun onFailure(exception: AuthenticationException) {
            // Handle error
        }
    })
    ```
  </Tab>
</Tabs>

* Exchange a refresh token for a session transfer token using 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">
  These samples use placeholder variables for dynamic variables. Replace the placeholders using your Auth0 domain, client\_id and an existing refresh\_token.
</Callout>

The Auth0 tenant returns a single-use and short-lived (1-minute lifetime) 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">
  If refresh token rotation is enabled, the exchange will also return a refresh token.

  If you requested an ID Token during authentication, this call will also return an ID Token.
</Callout>

#### Step 2: Send the Session Transfer Token through a URL or cookie

There are two options to send the  `session_transfer_token` to your web application based on the configured `allowed_authentication_methods`.

##### Option 1: Send the session\_transfer\_token as a cookie

If your web application using WebView or browser supports cookie injection, you can configure your native application to:

* Add the session\_transfer\_token into a cookie.
* Open the web application using WebView or browser.
* Log the web application to your Auth0 tenant or <Tooltip data-tooltip-id="react-containers-DefinitionTooltip-4" href="/docs/ja-jp/glossary?term=custom-domain" tip="カスタムドメイン: 特殊な名前、またはバニティ名を持つサードパーティのドメイン。" cta="用語集の表示">Custom Domain</Tooltip>. As the `session_transfer_token` is included in the cookie, the user is not prompted for first-factor authentication.

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" />

##### Option 2: Send the session\_transfer\_token as a URL parameter

If your web application does not support cookie injection, you can configure your native application using URL parameters to:

* Add the session\_transfer\_token as a URL parameter.
* Open the web application using  WebView or browser.
* Log the web application appending the `session_transfer_token` as a URL parameter to the [/authorize](https://auth0.com/docs/api/authentication/authorization-code-flow/authorize-application) endpoint. The Auth0 tenant authenticates the user without requiring first-factor authentication, as the session\_transfer\_token is valid and trusted

<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);
  });
  ```

  ```objc Obj-C lines theme={null}
  #import <Foundation/Foundation.h>

  NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:@"https://your_web_app_login_url/?session_transfer_token=YOUR_SESSION_TRANSFER_TOKEN"]
                                                         cachePolicy:NSURLRequestUseProtocolCachePolicy
                                                     timeoutInterval:10.0];
  [request setHTTPMethod:@"GET"];

  NSURLSession *session = [NSURLSession sharedSession];
  NSURLSessionDataTask *dataTask = [session dataTaskWithRequest:request
                                              completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
                                                  if (error) {
                                                      NSLog(@"%@", error);
                                                  } else {
                                                      NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *) response;
                                                      NSLog(@"%@", httpResponse);
                                                  }
                                              }];
  [dataTask resume];
  ```

  ```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
  ```

  ```swift Swift lines theme={null}
  import Foundation

  let request = NSMutableURLRequest(url: NSURL(string: "https://your_web_app_login_url/?session_transfer_token=YOUR_SESSION_TRANSFER_TOKEN")! as URL,
                                          cachePolicy: .useProtocolCachePolicy,
                                      timeoutInterval: 10.0)
  request.httpMethod = "GET"

  let session = URLSession.shared
  let dataTask = session.dataTask(with: request as URLRequest, completionHandler: { (data, response, error) -> Void in
    if (error != nil) {
      print(error)
    } else {
      let httpResponse = response as? HTTPURLResponse
      print(httpResponse)
    }
  })

  dataTask.resume()
  ```
</AuthCodeGroup>

### In your web application

<Callout icon="file-lines" color="#0EA5E9" iconType="regular">
  When the Session Transfer Token is sent as a cookie, no further configuration is needed as the browser sends the cookie in the `/authorize` endpoint request.
</Callout>

Implement Native to Web Web Single SSO in your web application using URL parameters by:

#### Option 1: Add the Session Transfer Token in your web application request

From the application login URL, redirect to the `/authorize` endpoint when the `session_transfer_token` is sent as a URL parameter.

<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);
  });
  ```

  ```objc Obj-C theme={null}
  #import <Foundation/Foundation.h>

  NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:@"https://{yourDomain}/authorize?session_transfer_token=YOUR_SESSION_TRANSFER_TOKEN&client_ID={yourClientId}&redirect_uri=YOUR_REDIRECT_URI&response_type=code"]
                                                         cachePolicy:NSURLRequestUseProtocolCachePolicy
                                                     timeoutInterval:10.0];
  [request setHTTPMethod:@"GET"];

  NSURLSession *session = [NSURLSession sharedSession];
  NSURLSessionDataTask *dataTask = [session dataTaskWithRequest:request
                                              completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
                                                  if (error) {
                                                      NSLog(@"%@", error);
                                                  } else {
                                                      NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *) response;
                                                      NSLog(@"%@", httpResponse);
                                                  }
                                              }];
  [dataTask resume];
  ```

  ```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"))
  ```

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

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

  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
  ```

  ```swift Swift theme={null}
  import Foundation

  let request = NSMutableURLRequest(url: NSURL(string: "https://{yourDomain}/authorize?session_transfer_token=YOUR_SESSION_TRANSFER_TOKEN&client_ID={yourClientId}&redirect_uri=YOUR_REDIRECT_URI&response_type=code")! as URL,
                                          cachePolicy: .useProtocolCachePolicy,
                                      timeoutInterval: 10.0)
  request.httpMethod = "GET"

  let session = URLSession.shared
  let dataTask = session.dataTask(with: request as URLRequest, completionHandler: { (data, response, error) -> Void in
    if (error != nil) {
      print(error)
    } else {
      let httpResponse = response as? HTTPURLResponse
      print(httpResponse)
    }
  })

  dataTask.resume()
  ```
</AuthCodeGroup>

#### Option 2: Add the Session Transfer Token to web applications using Auth0 SDKs

Auth0 SDKs do not support Native to Web Single SSO automatically and they will not include the `session_transfer_token` in the `/authorize` endpoint request.

Below are examples of web applications using Auth0 SDKs to redirect the `session_transfer_token` in the `/authorize` endpoint request:

##### Node (Express.js)

If your web application uses [Express.js](https://expressjs.com/) or the [Auth0 Express SDK](https://github.com/auth0/express-openid-connect), you can use the code below to add middleware support for `session_transfer_token`.

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

// Default Middleware with no customizations
// app.use(auth(config));

// Extending the middleware to auto detect session_transfer_token
app.use((req, res, next) => {
  const { session_transfer_token } = req.query;

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

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

##### SAML and WS-Federation

If your web application uses <Tooltip data-tooltip-id="react-containers-DefinitionTooltip-1" href="/docs/ja-jp/glossary?term=security-assertion-markup-language" tip="Security Assertion Markup Language（SAML）: パスワードなしに二者間で認証情報を交換できる標準化プロトコル。" cta="用語集の表示">SAML</Tooltip> or <Tooltip data-tooltip-id="react-containers-DefinitionTooltip-2" href="/docs/ja-jp/glossary?term=ws-fed" tip="Webサービスフェデレーション（WS-Fed）: ドメイン全体でユーザーIDを管理するためのプロトコル。" cta="用語集の表示">WS-Fed</Tooltip> service provider and Auth0 as the <Tooltip data-tooltip-id="react-containers-DefinitionTooltip-2" href="/docs/ja-jp/glossary?term=idp" tip="IDプロバイダー（IdP）: デジタルIDを保存および管理するサービス。" cta="用語集の表示">IdP</Tooltip>, you can send the `session_transfer_token` as an URL parameter to the Auth0 `/authorize` endpoint and the `redirect_uri` is the SAML or WS-Fed sign-in 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);
  });
  ```

  ```objc Obj-C theme={null}
  #import <Foundation/Foundation.h>

  NSDictionary *headers = @{ @"cookie": @"session_transfer_token=YOUR_SESSION_TRANSFER_TOKEN" };

  NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:@"https://{yourDomain}/samlp//{yourClientId}?session_transfer_token=YOUR_SESSION_TRANSFER_TOKEN"]
                                                         cachePolicy:NSURLRequestUseProtocolCachePolicy
                                                     timeoutInterval:10.0];
  [request setHTTPMethod:@"GET"];
  [request setAllHTTPHeaderFields:headers];

  NSURLSession *session = [NSURLSession sharedSession];
  NSURLSessionDataTask *dataTask = [session dataTaskWithRequest:request
                                              completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
                                                  if (error) {
                                                      NSLog(@"%@", error);
                                                  } else {
                                                      NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *) response;
                                                      NSLog(@"%@", httpResponse);
                                                  }
                                              }];
  [dataTask resume];
  ```

  ```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
  ```

  ```swift Swift theme={null}
  import Foundation

  let headers = ["cookie": "session_transfer_token=YOUR_SESSION_TRANSFER_TOKEN"]

  let request = NSMutableURLRequest(url: NSURL(string: "https://{yourDomain}/samlp//{yourClientId}?session_transfer_token=YOUR_SESSION_TRANSFER_TOKEN")! as URL,
                                          cachePolicy: .useProtocolCachePolicy,
                                      timeoutInterval: 10.0)
  request.httpMethod = "GET"
  request.allHTTPHeaderFields = headers

  let session = URLSession.shared
  let dataTask = session.dataTask(with: request as URLRequest, completionHandler: { (data, response, error) -> Void in
    if (error != nil) {
      print(error)
    } else {
      let httpResponse = response as? HTTPURLResponse
      print(httpResponse)
    }
  })

  dataTask.resume()
  ```
</AuthCodeGroup>

## Session Transfer Token with Actions

Using `session_transfer_token` with [Actions](/docs/ja-jp/customize/actions) allows you to configure post-authentication risk detection and response capabilities to enhance user protection.

To facilitate this, the post-login Action object **event.session\_transfer\_token** provides relevant information including unique `client_id`, `scope`, `request` information such as `ip`, `asn`, `user_agent` and `geoip` information such as, `cityName`, `countryCode` among others. To learn more, read [Actions Triggers: post-login - Event Object](/docs/ja-jp/customize/actions/explore-triggers/signup-and-login-triggers/login-trigger/post-login-event-object).

The Action code below allows you to dynamically reject a transaction based on geolocation information:

```javascript javascript lines theme={null}
/**
* Handler that will be called during the execution of a PostLogin flow.
*
* @param {Event} event - Details about the user and the context in which they are logging in.
* @param {PostLoginAPI} api - Interface whose methods can be used to change the behavior of the login.
*/
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")
   }
};
```

## Monitoring

You can monitor the Native to Web SSO activity by reviewing the Tenant [logs](/docs/ja-jp/deploy-monitor/logs).

* `sertft` : Successful Refresh Token exchange. This log will correspond to a Native to Web SSO exchange when the `audience` field is `"audience":"urn:$auth0Domain:session_transfer"`
* `fertft`: Failed Refresh Token exchange. This log will correspond to a Native to Web SSO exchange when the `audience` field is `"audience": "urn:$auth0Domain:session_transfer"`
