---
schema_version: "1"
id: 346e04f03ad6f2eaf8bd4e1caeffd5edf8fbf14783cb45245d6b33bfa7e653f5
title: OAuth 2.0 User-Agent Flow for Desktop or Mobile App Integration
collection: admin
version: current
locale: en-us
portal_url: https://docs.salesforce.com/admin/current/en-us/xcloud/264-0-0/remoteaccess_oauth_user_agent_flow_ca.md
canonical_url: https://help.salesforce.com/s/articleView?id=xcloud.remoteaccess_oauth_user_agent_flow_ca.htm&release=264.0.0&type=5
source_site: help.salesforce.com
content_type: documentation
content_hash: 395c10bfd0157ae003d671258caa3f96dccea8976ab2c2f05b07afb7c6de4346
description: With the OAuth 2.0 user-agent flow, users authorize a desktop or mobile app to access data by using an external or embedded browser. Client apps running in a browser using a scripting language such as JavaScript can also use this flow. This flow uses the OAuth 2.0 implicit grant type.
products:
  - Security
  - Cross Cloud
release: "264"
---
# OAuth 2.0 User-Agent Flow for Desktop or Mobile App Integration

With the OAuth 2.0 user-agent flow, users authorize a desktop or mobile app to access data by using an external or embedded browser. Client apps running in a browser using a scripting language such as JavaScript can also use this flow. This flow uses the [OAuth 2.0 implicit grant type](https://tools.ietf.org/html/rfc6749#section-4.2).

### Required Editions

<table class="slds-table slds-table_bordered slds-max-medium-table_stacked slds-m-bottom_small edition"><colgroup><col></colgroup><tbody><tr class=""><td class="slds-cell-wrap" style="vertical-align:top;">Available in: both Salesforce Classic and Lightning Experience</td></tr><tr class=""><td class="slds-cell-wrap" style="vertical-align:top;">Available in: <strong>All</strong> Editions</td></tr></tbody></table>

![Note](https://sf-zdocs-cdn-prod.zoominsoftware.com/tdta-xcloud-identity-264-0-0-production-enus/699dab6f-8f1a-4662-b24f-6521d5b747f7/images/icon_note.png)

Note Connected apps creation is restricted as of Spring ‘26. You can continue to use existing connected apps during and after Spring ‘26. However, we recommend using [external client apps](https://help.salesforce.com/s/articleView?id=xcloud.external_client_apps.htm&language=en_US) instead. If you must continue creating connected apps, contact Salesforce Support.

See [New connected apps can no longer be created in Spring ‘26](https://help.salesforce.com/s/articleView?id=005228017&type=1&language=en_US) for more details.

![Important](https://sf-zdocs-cdn-prod.zoominsoftware.com/tdta-xcloud-identity-264-0-0-production-enus/699dab6f-8f1a-4662-b24f-6521d5b747f7/images/icon_important.png)

Important For increased security, we recommend using the OAuth 2.0 web server flow with Proof Key for Code Exchange (PKCE) instead of the user-agent flow. We have also made it possible to block connected apps that use the user-agent flow. Many mobile apps, including Salesforce mobile apps, use the user-agent flow and, blocking the user-agent flow will break those apps.

With the user-agent flow, the connected app, which integrates the client app with the Salesforce API, receives the access token as an HTTP redirection. The connected app requests that the authorization server redirects the user-agent to a web server or to an accessible local resource. The web server can extract the access token from the response and pass it to the connected app. For security, the token response is provided as a hash tag (#) fragment on the URL. This format prevents the token from being passed to the server or to any other servers in referral headers.

![Warning](https://sf-zdocs-cdn-prod.zoominsoftware.com/tdta-xcloud-identity-264-0-0-production-enus/699dab6f-8f1a-4662-b24f-6521d5b747f7/images/icon_warning.png)

Warning Because the access token is encoded into the redirection URL, it can be exposed to the user and other apps on the device.

If you’re using JavaScript to authenticate, call `window.location.replace();` to remove the callback from the browser’s history.

![Note](https://sf-zdocs-cdn-prod.zoominsoftware.com/tdta-xcloud-identity-264-0-0-production-enus/699dab6f-8f1a-4662-b24f-6521d5b747f7/images/icon_note.png)

Note Connected apps for these types of clients can protect per-user secrets. But the client secret is accessible and exploitable because client executables reside on the user’s device. For this reason, the user-agent flow doesn’t use the client secret. Authorization is based on the user-agent’s same-origin policy. Also, the user-agent flow doesn’t support out-of-band posts.

For example, you use Salesforce Mobile SDK to build a mobile app that looks up customer contact information from your Salesforce org. Mobile SDK implements the OAuth 2.0 user-agent flow for your connected app, integrating the mobile app with your Salesforce API and giving it authorized access to the defined data. The flow follows these steps.

1. The user opens the mobile app.
2. The connected app directs the user to Salesforce to authenticate and authorize the mobile app.
3. The user approves access for this authorization flow.
4. The connected app receives the callback from Salesforce to the redirect URL, which extracts the access and refresh tokens.
5. The connected app uses the access token to access data on the user’s behalf.

## Redirection to Authorization Endpoint

To get a user’s authorization to access Salesforce data, the connected app redirects the user to the authorization endpoint. Here’s an example HTTP redirection.

```
https://login.salesforce.com/services/oauth2/authorize?response_type=token&
client_id=3MVG9lKcPoNINVBIPJjdw1J9LLJbP_pqwoJYyuisjQhr_LLurNDv7AgQvDTZwCoZuDZrXcPCmBv4o.8ds.5iE&
redirect_uri=https://www.customercontactinfo.com/user_callback.jspk&
state=mystate
```

Include these parameters in the URL.

 
| Parameter | Description |
| --- | --- |
| OAuth 2.0 authorization endpoint | The Salesforce instance’s OAuth 2.0 authorization endpoint. Connected apps send OAuth authorization requests to this endpoint. |
| `client_id` | The consumer key of the connected app. To access the consumer key, from the App Manager, find the connected app and select **View** from the dropdown. Then click **Manage Consumer Details**. You're sometimes prompted to verify your identity before you can view the consumer key. |
| `redirect_uri` | The URL where users are redirected after a successful authentication. The redirect URI must match one of the values in the connected app’s Callback URL field. Otherwise, the approval fails. You can find the redirect URI on the connected app’s Manage Connected Apps page or from the connected app’s definition. This value must be URL encoded. |
| `response_type` | Use the `token` value. You can also use the `token id_token` value, with the `openid` scope and a `nonce` parameter. If you specify `token id_token`, Salesforce returns an ID token in the response. |

These parameters are optional.

<table class="slds-table slds-table_bordered slds-max-medium-table_stacked slds-m-bottom_small ">
        <colgroup>
          <col>
          <col>
        </colgroup>
        <thead class="slds-text-title_caps ">
          <tr class="">
            <th scope="col" class="slds-cell-wrap" style="vertical-align:top;" id="d43709e232">Parameter</th>
            <th scope="col" class="slds-cell-wrap" style="vertical-align:top;" id="d43709e235">Description</th>
          </tr>
        </thead>
        <tbody>
          <tr class="">
            <td data-label="Parameter" class="slds-cell-wrap" style="vertical-align:top;" headers="d43709e232 ">
              <code>scope</code>
            </td>

            <td data-label="Description" class="slds-cell-wrap" style="vertical-align:top;" headers="d43709e235 ">
              <p>Permissions that define the type of protected resources a connected app can
                access. You assign scopes to a connected app when you build it, and they’re included
                with the OAuth tokens during the authorization flow.</p>
              <p style="margin-bottom:0;">If you don’t include this
                parameter, all scopes assigned to the connected app are requested. The scopes
                passed in this parameter must be a subset of the registered scopes. For valid
                parameters, see <a href="https://help.salesforce.com/s/articleView?id=xcloud.remoteaccess_oauth_tokens_scopes.htm&amp;type=5&amp;language=en_US" target="_blank">OAuth Scopes</a>.</p>
            </td>

          </tr>
          <tr class="">
            <td data-label="Parameter" class="slds-cell-wrap" style="vertical-align:top;" headers="d43709e232 ">
              <code>state</code>
            </td>

            <td data-label="Description" class="slds-cell-wrap" style="vertical-align:top;" headers="d43709e235 ">
              <span>Any state that the external web service requests to be sent to the callback URL.
                This value must be URL encoded.</span>
            </td>

          </tr>
          <tr class="">
            <td data-label="Parameter" class="slds-cell-wrap" style="vertical-align:top;" headers="d43709e232 ">
              <code>display</code>
            </td>

            <td data-label="Description" class="slds-cell-wrap" style="vertical-align:top;" headers="d43709e235 ">
              <p>Changes the display type of the login and authorization pages. Salesforce
                supports these values.</p>
              <ul>
                <li><code>page</code>—Full-page authorization screen (default).</li>

                <li><code>popup</code>—Compact dialog optimized for modern web browser
                  popups.</li>

                <li><code>touch</code>—Mobile-optimized dialog designed for modern mobile
                  devices, such as Android and iPhone.</li>

                <li><code>mobile</code>—Mobile-optimized dialog designed for less capable
                  devices, such as BlackBerry operating system 5.</li>

              </ul>
            </td>

          </tr>
          <tr class="">
            <td data-label="Parameter" class="slds-cell-wrap" style="vertical-align:top;" headers="d43709e232 ">
              <code>login_hint</code>
            </td>

            <td data-label="Description" class="slds-cell-wrap" style="vertical-align:top;" headers="d43709e235 ">
              <p>Provides a valid username value to prepopulate the login page with the
                username, such as <code>login_hint=username@company.com</code>. If a user
                already has an active session in the browser, the <code>login_hint</code>
                parameter does nothing, and the active user session continues.</p>
              <p style="margin-bottom:0;">To pass the
                <code>login_hint</code> parameter for Experience Cloud sites, also pass the
                <code>prompt=login</code> parameter. Together, these parameters redirect the
                user to the login page with the correct login hint.
              </p>
            </td>

          </tr>
          <tr class="">
            <td data-label="Parameter" class="slds-cell-wrap" style="vertical-align:top;" headers="d43709e232 ">
              <code>nonce</code>
            </td>

            <td data-label="Description" class="slds-cell-wrap" style="vertical-align:top;" headers="d43709e235 ">
              <span>Use with the <code>openid</code> scope to request a user ID token. The user
                ID token is returned in the response. This parameter is optional, but it helps to
                detect replay attacks.</span>
            </td>

          </tr>
          <tr class="">
            <td data-label="Parameter" class="slds-cell-wrap" style="vertical-align:top;" headers="d43709e232 ">
              <code>prompt</code>
            </td>

            <td data-label="Description" class="slds-cell-wrap" style="vertical-align:top;" headers="d43709e235 ">
              <p>Specifies how the authorization server prompts the user for reauthentication
                and reapproval. Salesforce supports these values.</p>
              <ul>
                <li><code>login</code>—The authorization server must prompt the user for
                  reauthentication, forcing the user to log in again.</li>

                <li><code>consent</code>—The authorization server must prompt the user for
                  reapproval before returning information to the client.</li>

                <li><code>select_account</code>—If presented, take one of these actions.<ul>
                    <li>If zero or one hint is available and the user is logged in, show the
                      approval page without prompting for login.</li>

                    <li>If zero or one hint is available and the user isn’t logged in, prompt for
                      login.</li>

                    <li>If more than one hint is available, show the account chooser.</li>

                  </ul>
                </li>

              </ul>
              <p style="margin-bottom:0;">You can pass <code>login</code> and <code>consent</code> values,
                separated by a space, to require the user to log in and reauthenticate. For
                example: <code>?prompt=login%20consent</code></p>
            </td>

          </tr>
          <tr class="">
            <td data-label="Parameter" class="slds-cell-wrap" style="vertical-align:top;" headers="d43709e232 ">
              <code>prompt</code>
            </td>

            <td data-label="Description" class="slds-cell-wrap" style="vertical-align:top;" headers="d43709e235 ">
              <p>Specifies how the authorization server prompts the user for reauthentication
                and reapproval. Salesforce supports these values.</p>
              <ul>
                <li><code>login</code>—The authorization server must prompt the user for
                  reauthentication, forcing the user to log in again.</li>

                <li><code>consent</code>—The authorization server must prompt the user for
                  reapproval before returning information to the client.</li>

                <li><code>select_account</code>—If presented, take one of these actions.<ul>
                    <li>If zero or one hint is available and the user is logged in, show the
                      approval page without prompting for login.</li>

                    <li>If zero or one hint is available and the user isn’t logged in, prompt for
                      login.</li>

                    <li>If more than one hint is available, show the account chooser.</li>

                  </ul>
                </li>

              </ul>
              <p style="margin-bottom:0;">You can pass <code>login</code> and <code>consent</code> values,
                separated by a space, to require the user to log in and reauthenticate. For
                example: <code>?prompt=login%20consent</code></p>
            </td>

          </tr>
          <tr class="">
            <td data-label="Parameter" class="slds-cell-wrap" style="vertical-align:top;" headers="d43709e232 ">
              <code>sso_provider</code>
            </td>

            <td data-label="Description" class="slds-cell-wrap" style="vertical-align:top;" headers="d43709e235 ">The developer name of a single sign-on (SSO) identity provider configured with
              a My Domain login URL or Experience Cloud site URL. You can use this parameter to
              create an SSO experience that feels like your app is integrated with the SSO
              provider. For example, you can use this parameter to offer SSO in a Headless
              Identity implementation.</td>

          </tr>
        </tbody>
      </table>

## User Authenticates and Authorizes Access

The user logs into Salesforce with their credentials. The user interacts with the authorization endpoint directly, so the application never sees the user’s credentials.

![Login page to Salesforce org](https://sf-zdocs-cdn-prod.zoominsoftware.com/tdta-xcloud-identity-264-0-0-production-enus/699dab6f-8f1a-4662-b24f-6521d5b747f7/identity/images/remoteaccess_authflow_login.png)

After a successful login, Salesforce redirects users to the approval page to grant access to the app.

## Salesforce Grants Access Token

After a user approves access to a connected app, Salesforce redirects the user to the callback URL. Included in the redirection is the granted access token, which the connected app can extract and use to access data on the user’s behalf.

Here’s an example of the callback from the server. The response is behind a hash tag (#), rather than as HTTP query parameters.

```
https://www.customercontactinfo.com/user_callback.jsp#
access_token=00Dx0000000BV7z%21AR8AQBM8J_xr9kLqmZIRyQxZgLcM4HVi41aGtW0qW3JCzf5xd
TGGGSoVim8FfJkZEqxbjaFbberKGk8v8AnYrvChG4qJbQo8&
refresh_token=5Aep8614iLM.Dq661ePDmPEgaAW9Oh_L3JKkDpB4xReb54_pZfVti1dPEk8aimw4Hr9ne7VXXVSIQ%3D%3D&
instance_url=https://yourInstance.salesforce.com&
id=https://login.salesforce.com%2Fid%2F00Dx0000000BV7z%2F005x00000012Q9P&
issued_at=1278448101416&
signature=miQQ1J4sdMPiduBsvyRYPCDozqhe43KRc1i9LmZHR70%3D&
scope=id+api+refresh_token&
token_type=Bearer&
state=mystate
```

The response in the example contains these parameters following the hash tag (#). The connected app’s callback URL precedes the hash tag (#).

<table class="slds-table slds-table_bordered slds-max-medium-table_stacked slds-m-bottom_small ">
        <colgroup>
          <col>
          <col>
        </colgroup>
        <thead class="slds-text-title_caps ">
          <tr class="">
            <th scope="col" class="slds-cell-wrap" style="vertical-align:top;" id="d43709e517">Parameter</th>
            <th scope="col" class="slds-cell-wrap" style="vertical-align:top;" id="d43709e520">Description</th>
          </tr>
        </thead>
        <tbody>
          <tr class="">
            <td data-label="Parameter" class="slds-cell-wrap" style="vertical-align:top;" headers="d43709e517 ">
              <code>access_token</code>
            </td>

            <td data-label="Description" class="slds-cell-wrap" style="vertical-align:top;" headers="d43709e520 ">OAuth token that a connected app uses to request access to a protected resource
              on behalf of the client application. Additional permissions in the form of scopes
              can accompany the access token.</td>

          </tr>
          <tr class="">
            <td data-label="Parameter" class="slds-cell-wrap" style="vertical-align:top;" headers="d43709e517 ">
              <code>refresh_token</code>
            </td>

            <td data-label="Description" class="slds-cell-wrap" style="vertical-align:top;" headers="d43709e520 ">
              <p>Token obtained from the web server, user-agent, or hybrid app token flow. This
                value is a secret. Take appropriate measures to protect it. </p>
              <p>The refresh token for
                the user-agent flow is only issued if you requested
                <code>scope=refresh_token</code> and one of these scenarios is true.
              </p>
              <ul>
                <li>The redirect URL uses a custom protocol.</li>

                <li>The redirect URL host matches the request host and includes the servlet
                  <samp class="filepath">services/oauth2/success</samp>. For example:<ul>
                    <li><samp class="filepath">https://login.salesforce.com/services/oauth2/success</samp></li>

                    <li><samp class="filepath">https://test.salesforce.com/services/oauth2/success</samp></li>

                    <li><samp class="filepath">https://<var>domain</var>.my.salesforce.com/services/oauth2/success</samp></li>

                    <li><samp class="filepath">https://<var>site_url</var>/services/oauth2/success</samp></li>

                  </ul>
                </li>

                <li>The redirect URL is
                  <samp class="filepath">https://mobileauth.salesforce.com/oauth/done</samp>
                </li>

                <li>The redirect URL is
                  <samp class="filepath">https://mobileauth.salesforce.com/analytics/oauth/done</samp>
                </li>

              </ul>
            </td>

          </tr>
          <tr class="">
            <td data-label="Parameter" class="slds-cell-wrap" style="vertical-align:top;" headers="d43709e517 ">
              <code>instance_url</code>
            </td>

            <td data-label="Description" class="slds-cell-wrap" style="vertical-align:top;" headers="d43709e520 ">A URL indicating the instance of the user’s org. For example:
              <code>https://<var>yourInstance</var>.salesforce.com/</code>.
            </td>

          </tr>
          <tr class="">
            <td data-label="Parameter" class="slds-cell-wrap" style="vertical-align:top;" headers="d43709e517 ">
              <code>id</code>
            </td>

            <td data-label="Description" class="slds-cell-wrap" style="vertical-align:top;" headers="d43709e520 ">An identity URL that can be used to identify the user and to query for more
              information about the user. See <a href="https://help.salesforce.com/articleView?id=remoteaccess_using_openid.htm&amp;language=en_US" target="_blank">Identity URLs</a>.</td>

          </tr>
          <tr class="">
            <td data-label="Parameter" class="slds-cell-wrap" style="vertical-align:top;" headers="d43709e517 ">
              <code>issued_at</code>
            </td>

            <td data-label="Description" class="slds-cell-wrap" style="vertical-align:top;" headers="d43709e520 ">Time stamp of when the signature was created in milliseconds.</td>

          </tr>
          <tr class="">
            <td data-label="Parameter" class="slds-cell-wrap" style="vertical-align:top;" headers="d43709e517 ">
              <code>signature</code>
            </td>

            <td data-label="Description" class="slds-cell-wrap" style="vertical-align:top;" headers="d43709e520 ">Base64-encoded HMAC-SHA256 signature signed with the
              <code>client_secret</code>. The signature can include the concatenated ID and
              <code>issued_at value</code>, which you can use to verify that the identity
              URL hasn’t changed since the server sent it.
            </td>

          </tr>
          <tr class="">
            <td data-label="Parameter" class="slds-cell-wrap" style="vertical-align:top;" headers="d43709e517 ">
              <code>scope</code>
            </td>

            <td data-label="Description" class="slds-cell-wrap" style="vertical-align:top;" headers="d43709e520 ">
              <p>The scopes associated with the access token.</p>
              <p>Scopes further define the type
                of protected resources that the client can access. You assign scopes to a
                connected app when you build it, and they’re included with the OAuth tokens during
                the authorization flow. </p>
              <p style="margin-bottom:0;">For valid parameters, see <a href="https://help.salesforce.com/s/articleView?id=xcloud.remoteaccess_oauth_tokens_scopes.htm&amp;type=5&amp;language=en_US" target="_blank">OAuth Scopes</a>.</p>
            </td>

          </tr>
          <tr class="">
            <td data-label="Parameter" class="slds-cell-wrap" style="vertical-align:top;" headers="d43709e517 ">
              <code>token_type</code>
            </td>

            <td data-label="Description" class="slds-cell-wrap" style="vertical-align:top;" headers="d43709e520 ">A <code>Bearer</code> token type, which is used for all responses that
              include an access token.</td>

          </tr>
          <tr class="">
            <td data-label="Parameter" class="slds-cell-wrap" style="vertical-align:top;" headers="d43709e517 ">
              <code>state</code>
            </td>

            <td data-label="Description" class="slds-cell-wrap" style="vertical-align:top;" headers="d43709e520 ">The state requested by the client. This value is included only if the
              <code>state</code> parameter is included in the original query string.
            </td>

          </tr>
        </tbody>
      </table>

The response can also contain these parameters.

<table class="slds-table slds-table_bordered slds-max-medium-table_stacked slds-m-bottom_small ">
        <colgroup>
          <col>
          <col>
        </colgroup>
        <thead class="slds-text-title_caps ">
          <tr class="">
            <th scope="col" class="slds-cell-wrap" style="vertical-align:top;" id="d43709e733">Parameter</th>
            <th scope="col" class="slds-cell-wrap" style="vertical-align:top;" id="d43709e736">Description</th>
          </tr>
        </thead>
        <tbody>
          <tr class="">
            <td data-label="Parameter" class="slds-cell-wrap" style="vertical-align:top;" headers="d43709e733 ">
              <code>id_token</code>
            </td>

            <td data-label="Description" class="slds-cell-wrap" style="vertical-align:top;" headers="d43709e736 ">
              <p>A signed data structure that contains authenticated user attributes, including
                a unique identifier for the user and a timestamp indicating when the token was
                issued. It also identifies the requesting client app. See <a href="http://openid.net/specs/openid-connect-basic-1_0-28.html" target="_blank">OpenID Connect specifications</a>.</p>
              <p style="margin-bottom:0;">This parameter is returned if the
                <samp class="parmname">scope</samp> parameter includes
                <code>openid</code>.
              </p>
            </td>

          </tr>
          <tr class="">
            <td data-label="Parameter" class="slds-cell-wrap" style="vertical-align:top;" headers="d43709e733 ">
              <code>sfdc_site_url</code>
            </td>

            <td data-label="Description" class="slds-cell-wrap" style="vertical-align:top;" headers="d43709e736 ">If the user is a member of an Experience Cloud site, the site URL is
              provided.</td>

          </tr>
          <tr class="">
            <td data-label="Parameter" class="slds-cell-wrap" style="vertical-align:top;" headers="d43709e733 ">
              <code>sfdc_site_id</code>
            </td>

            <td data-label="Description" class="slds-cell-wrap" style="vertical-align:top;" headers="d43709e736 ">If the user is a member of an Experience Cloud site, the user’s site ID is
              provided.</td>

          </tr>
        </tbody>
      </table>