Loading
Salesforce now sends email only from verified domains. Read More
Identify Your Users and Manage Access
Table of Contents
Select Filters

          No results
          No results
          Here are some search tips

          Check the spelling of your keywords.
          Use more general search terms.
          Select fewer filters to broaden your search.

          Search all of Salesforce Help
          Headless Identity APIs: Headless Guest Flow for Public Clients

          Headless Identity APIs: Headless Guest Flow for Public Clients

          Some users interact with your off-platform app but don’t log in or register. You can issue identifiers in the form of unique visitor ID (UVIDs) for these unknown visitors with the Headless Guest Flow. If the user decides to log in or register, you can pass the identifier into a named user flow, like a headless login flow. Use guest user identity as a tool for carrying context from guest user sessions to named user sessions. This flow is a variation of the Authorization Code and Credentials Flow.

          Required Editions

          Available in: both Salesforce Classic (not available in all orgs) and Lightning Experience
          Available in: Enterprise, Unlimited, and Developer Editions

          Before setting up this flow, complete these steps.

          For example, you host an ecommerce app outside of the Salesforce platform. You want users to be able to save items to a cart without logging in. You can use the guest user flow to generate a UVID for the user, and you can store the user’s cart information and tie it to the UVID. When the user eventually logs in or registers, you pass the UVID into a headless login or registration flow. Because you have the cart context from the UVID, you can save the user’s items, giving your users a better experience.

          The shopping cart example is just one of many possibilities when it comes to the UVID and guest flow. Other possibilities include understanding what makes your users want to sign up for your app and remembering their preferences.

          The guest flow and UVID are supported only for JSON Web Token (JWT)-based access tokens. To connect the UVID to a named user, you must configure the named user flow to issue JWT-based access tokens too.

          These instructions tell you how to implement the flow for a public client, like a single-page app, that can’t keep confidential information private. Public clients have some extra security considerations. Compared to a private client like a client-server app, they don’t have a private backend to store the consumer secret, which acts as a password to secure the code exchange. With nowhere to store a consumer secret, the app can’t risk leaking it. To replace the role of the consumer secret, you can use the Proof Key for Code Exchange (PKCE) extension instead. This extension protects your app with parameters that only you and Salesforce can verify. We always recommend implementing PKCE for a public client.

          Here’s an overview of the guest flow. These steps cover the flow up to the point when the guest user is identified, but not logged in.

          Sequence diagram showing headless guest user flow for public clients
          • The unknown visitor arrives at the app or performs an action like clicking a button (1).
          • The app looks for a UVID, and if it can’t find one, it generates a value.
          • If you’re using the Proof Key for Code Exchange (PKCE) extension, which we strongly recommend, the app generates PKCE parameters.
          • To get an authorization code, your app headlessly sends the UVID to the Salesforce authorization endpoint (services/oauth2/authorize) in a GET or POST request.
          • Salesforce validates the UVID and returns a 302 redirect to a preconfigured URL containing the authorization code. The redirect is processed within the browser, and the response is delivered to the callback endpoint.
          • The callback endpoint extracts the authorization code and returns it to your app.
          • Your app receives the authorization code and initiates a code exchange by sending the code and other parameters in a POST request to the Salesforce token endpoint (services/oauth2/token).
          • Salesforce validates the request and returns a guest JWT-based access token with the UVID in the subject claim.
          • Your app processes the response and creates a guest session, persisting the UVID value.
          • The end user now has a guest session keyed to the UVID value returned in the access token.

          Like other variations of the Authorization Code and Credentials Flow, for a public client, this flow requires a callback endpoint that can handle the 302 redirect and return the authorization code and other parameters to your app. If you do the code exchange in your browser, you can use the Salesforce /services/oauth2/echo endpoint. It automatically parses the 302 redirect, extracts the parameters, and returns them to your app in JSON format. We use the echo endpoint in the code examples for this flow.

          Unknown End User Arrives at Your App

          The flow starts when an end user visits your app. You can also configure it to start when the user performs an action, such as saving an item to a cart.

          App Generates a UVID

          Your app tries to find a UVID associated with this user. For example, it looks for browser cookies from any previous visits to the app. If the app can’t find a UVID, it generates one. Salesforce doesn’t play a role in generating the UVID. Its generation, storage, and maintenance are entirely up to you. The only requirement is that the UVID must be a Version 4 universally unique identifier (v4 UUID).

          App Generates PKCE Parameters

          If you’re using PKCE, your app generates code_verifier and code_challenge parameters.

          The PKCE specification defined in RFC 7636 also includes an optional code_challenge_method parameter that you can send in the authorization request. Salesforce ignores any value that you send in this parameter and defaults to SHA256.

          App Exchanges the UVID for an Authorization Code

          Your app headlessly sends a GET or POST request to the Salesforce authorization endpoint on your Experience Cloud site. The request contains the UVID and other parameters to identify the app and specify the type of request.

          You have two options for how you send the UVID in this request. You can either send a plain UVID value, or send a JWT-based access token with the UVID minted into it. For example, if you have a JWT-based access token from a previous session, sending the token to the authorization endpoint is an easy way to reuse it without specifically parsing it for the UVID.

          Include these headers in your request.

          Authorization Request: Headers
          Header Required? Description
          Uvid-Hint Required if you don’t send the UVID in the request body. You must always include a UVID—whether it’s sent in the header or in the request body.

          Contains either the UVID as a plain value or a JWT-based access token with a UVID minted into it.

          If you send the UVID as a plain value, include a UVID prefix before the value so that the request is formatted as Uvid-Hint: UVID <UVID value>.

          If you send a JWT-based access token with a UVID, include a JWT prefix before the value, such as Uvid-Hint: JWT <access token containing UVID>.

          Auth-Request-Type Yes. Specifies the type of request you want to make to Salesforce. For headless passwordless login, this value must be set to guest.

          Include these parameters in the request body.

          Authorization Request: Body Parameters
          Parameter Required? Description
          uvid_hint Required if you don’t include the UVID in the header.

          Contains either the UVID as a plain value or a JWT-based access token with a UVID minted into it.

          If you send the UVID as a plain value, include a UVID prefix before the value so that the request is formatted as uvid_hint=UVID <UVID value>.

          If you send a JWT-based access token with a UVID, include a JWT prefix before the value, such as uvid_hint=JWT <access token containing UVID>.

          client_id Yes. The consumer key of the external client app or connected app.
          response_type Yes. The OAuth 2.0 grant type that your app requests. Because this flow is a variation of the Authorization Code and Credentials Flow, this value must be code_credentials.
          redirect_uri Yes.

          The URL where users are redirected after successful authentication. The redirect_uri must match one of the values in the external client app or connected app Callback URL field. Otherwise, the approval fails. This value must be URL encoded.

          For this flow, you can use the echo endpoint, https://MyExperienceCloudSite.my.site.com/services/oauth2/echo, as your callback endpoint.

          code_challenge Only if you’re using PKCE, which we always recommend, especially for a public client.

          Specifies the SHA256 hash value of the code_verifier value in the token request. Set this parameter to help prevent authorization code interception attacks. The value must be Base-64 URL encoded as defined in https://tools.ietf.org/html/rfc4648#section-5

          If a code_challenge is provided in the authorization request and a code_verifier is provided in the token request, Salesforce compares the two values. If the code_challenge is invalid or doesn’t match, the login fails with the invalid_request error code.

          If the code_challenge is provided in the authorization request, but there’s no code_verifier in the token request, the login fails with the invalid_grant error code.

          scope Yes.

          Permissions that define the type of protected resources an external client app or connected app can access. The values that you send in this request must match or be a subset of the scopes assigned to your app.

          For more information about each scope and its purpose, see OAuth Tokens and Scopes.

          Check out these example authorization requests, which all implement PKCE.

          Here’s an example request where the UVID is passed as a plain value in the request header.

          POST /services/oauth2/authorize? HTTP 1.1
          Host: MyExperienceCloudSite.my.site.com
          Uvid-Hint: UVID abcd-1234-efgh
          Auth-Request-Type: guest
          
          response_type=code_credentials&
          client_id=***********&
          redirect_uri=https://www.MyExperienceCloudSite.my.site.com/services/oauth2/echo&
          code_challenge=********&
          scope=openid
          

          In this example, the UVID is passed in a JWT-based access token in the header.

          POST /services/oauth2/authorize? HTTP 1.1
          Host: MyExperienceCloudSite.my.site.com
          Uvid-Hint: JWT **************
          Auth-Request-Type: guest
          
          response_type=code_credentials&
          client_id=***********&
          redirect_uri=https://www.MyExperienceCloudSite.my.site.com/services/oauth2/echo&
          code_challenge=********&
          scope=openid
          

          Here’s an example where the UVID is passed as a plain value in the request body.

          POST /services/oauth2/authorize? HTTP 1.1
          Host: MyExperienceCloudSite.my.site.com
          Auth-Request-Type: guest
          
          uvid_hint=UVID abcd-1234-efgh&
          response_type=code_credentials&
          client_id=***********&
          redirect_uri=https://www.MyExperienceCloudSite.my.site.com/services/oauth2/echo&
          code_challenge=********&
          scope=openid
          

          Salesforce Returns a 302 Redirect

          Salesforce validates the UVID. If the UVID was passed as a plain value, Salesforce validates its format. If it was passed as a JWT-based access token, Salesforce checks the validity of the token.

          Salesforce then returns an HTTP 302 redirect to a preconfigured URL containing the authorization code. If the flow is happening in the browser, the 302 redirect is processed in the browser and Salesforce automatically sends the redirect response to the redirect URL, which is the callback endpoint. Here’s an example preconfigured URL.

          https://www.MyDomainName.my.site.com/services/apexrest/code/exchange?code=aPrxC1*******
          &sfdc_community_url=https%3A%2F%2FMyDomainName.my.site.com&sfdc_community_id=0DBxxxxxxxxxxxx

          Callback Endpoint Sends the Authorization Code to Your App

          The callback endpoint extracts the authorization code and returns it to your app. In these code examples, the redirect URL points to the /services/oauth2/echo callback endpoint on the Experience Cloud site. This endpoint automatically parses the 302 redirect, extracts the authorization code and other parameters, and returns them to your app in JSON format.

          App Initiates Code Exchange

          Your app receives the code response with the authorization and other parameters. It exchanges the code for an access token by sending a headless POST request to the /services/oauth2/token endpoint.

          Include one header in the request.

          Code Exchange: Header
          Parameter Required? Description
          Auth-Request-Type Yes. Specifies the type of request you want to make to Salesforce. For headless passwordless login, this value must be set to guest.
          Uvid-Hint Yes.

          Contains either the UVID as a plain value, or a JWT-based access token with a UVID minted into it.

          For the code exchange, don’t include a prefix for the UVID. For example, if you pass the UVID as a plain value, the header is just Uvid-Hint: abcd-1234-efgh. If you pass in a JWT-based access token, it’s Uvid-Hint: <access token containing UVID>.

          Include these parameters in the request body.

          Code Exchange: Body Parameters
          Parameter Required? Description
          code Yes. The authorization server creates an authorization code, which is a short-lived token, and passes it to the client after successful authentication. The client sends the authorization code to the authorization server to obtain an access token and, optionally, a refresh token.
          client_id Yes. The consumer key of the external client app or connected app.
          redirect_uri Yes.

          The URL where users are redirected after a successful authentication. The redirect URI must match one of the values in the external client app or connected app Callback URL field. Otherwise, the approval fails. This value must be URL encoded.

          For this flow, you can use the echo endpoint, https://MyExperienceCloudSite.my.site.com/services/oauth2/echo, as your callback endpoint.

          grant_type Yes. The type of validation that the external client app or connected app can provide to prove it’s a safe visitor. Because this flow is a variation of the Authorization Code and Credentials Flow, the value must be authorization_code.
          code_verifier Only if you’re using PKCE.

          Specifies 128 bytes of random data with high entropy to make guessing the code value difficult. Set this parameter to help prevent authorization code interception attacks. The value must be base64url-encoded as defined in https://datatracker.ietf.org/doc/html/rfc4648#section-5.

          If there’s a code_verifier value in the token request and a code_challenge value in the authorization request, Salesforce compares the two values. If the code_verifier is invalid or doesn’t match, the login fails with the invalid_grant error code.

          If the code_verifier value is in the token request, but there’s no code_challenge value in the authorization request, the login fails with the invalid_grant error code.

          Here’s an example token request that implements PKCE. In this example, the UVID is sent as a plain value.

          POST services/oauth2/token? HTTP 1.1
          Host: MyExperienceCloudSite.my.site.com
          Uvid-Hint: abcd-1234-efgh
          Auth-Request-Type: guest
          
          code=********&
          client_id=**********&
          redirect_uri=https://MyExperienceCloudSite.my.site.com/services/oauth2/echo&
          grant_type=authorization_code&
          code_verifier=*******

          Salesforce Grants a JWT-Based Access Token

          After validating the app’s credentials. Salesforce returns a guest JWT-based access token and a state to the browser. The guest access token contains the UVID in the subject (sub) claim. Here’s an example snippet of a JWT-based access token. As a reminder, these tokens have three components: a header, payload, and signature. This example shows you the payload with the UVID in the sub claim. As you can see, the value is prefixed with uvid.

          {
            "tnk": "example/00XXXXXX",
            "ver": "1.0",
            "kid": "CORE_ATJWT************",
            "tty": "sfdc-core-token",
            "typ": "JWT",
            "alg": "RS256"
          }
          
          {
            "scp": "open_id",
            "aud": [
              "https://example.com"
            ],
            "sub": "uvid:abcd-1234-efgh",
            "nbf": "1675197036",
            "iss": "https://MyExperienceCloudSite.my.site.com",
            "exp": "1675198836",
            "iat": "1675197036",
             jti”: xRb**********”
            "client_id": "**********"
          }

          For a full explanation of each claim in a JWT-based access token, see JWT-Based Access Tokens in Salesforce Help.

          App Creates a Guest Session

          Your app processes the access token response and creates a guest session, persisting the UVID value.

          Unknown User Is Now Identified

          The unknown end user now has a guest session tied to the UVID value returned in the JWT-based access token. At this point, it’s up to you what you want to do with the UVID. To learn how to pass it into a named user authorization flow, see Headless Identity APIs: Extending the Headless Guest Flow into a Named User Flow.

           
          Loading
          Salesforce Help | Article