无头身份 API:专用客户端的无头来宾流
对于与您的平台外应用程序交互但不一定登录的用户,您可以使用无头来宾流识别具有唯一访客 ID (UVID) 的用户。当用户登录或注册时,您可以继续使用 UVID 并维护与之相关的任何上下文信息,例如用户的首选项。该流是授权代码和凭据流的变体。
所需的 Edition
| 适用于:Salesforce Classic(并非在所有组织中可用)和 Lightning Experience |
| 适用于:Enterprise、Unlimited 和 Developer Edition |
在设置此流前,请完成这些步骤。
- 完成无头身份的先决条件
- 使用以下选项之一,将平台外应用程序与 Salesforce 集成。请确保您为来宾流配置附加策略。
例如,您可以在 Salesforce 平台外托管 Ecommerce 应用程序。您希望用户能够在不登录的情况下将商品保存到购物车中。您可以使用来宾用户流为用户生成 UVID,并且可以存储用户的购物车信息并将其绑定到 UVID。当用户最终登录或注册时,您将 UVID 传递给无头登录或注册流。因为您有来自 UVID 的购物车上下文,所以您可以保存用户的商品,给他们更好的体验。
对于 UVID 和来宾流,购物车示例只是许多可能性中的一种。其他可能性包括了解是什么让用户想要注册您的应用程序,并记住他们的首选项。
只有基于 JSON Web 令牌 (JWT) 的访问令牌才支持来宾流和 UVID。要将 UVID 连接到命名用户,您必须配置命名用户流,使其也可以发布基于 JWT 的访问令牌。
这些说明告诉您如何为拥有自己后端的专用客户端实施该流。专用客户端有一个安全的地方来存储应用程序的使用者密码,该密码用作代码交换的密码,因此我们建议您在请求访问令牌时发送使用者密码。
我们还建议您通过实施 OAuth 2.0 代码交换验证密钥 (PKCE) 扩展来进一步保护您的流。PKCE 有助于确保启动流的客户端就是完成流的客户端。有关 PKCE 的工作方式和实施方式的更多信息,请参见将 PKCE 扩展构建到实施中。
以下是来宾流的概述。这些步骤涵盖了来宾用户被识别但未登录时的流。
- 未知访问者到达应用程序,或执行单击按钮等操作 (1)。
- 应用程序查找 UVID。如果找不到,将从客户端后端请求 UVID (2)。
- 提出请求后,客户端后端会生成 UVID 并发送给应用程序 (3)。
- 应用程序接收 UVID (4a)。
- 如果您使用 PKCE,应用程序会生成 PKCE 参数 (4b)。
- 要获取授权代码,应用程序会在无头 GET 或 POST 请求中向授权端点 (
services/oauth2/authorize) (5) 发送 UVID。 - Salesforce 验证 UVID 并将 302 重定向返回到包含授权代码的预配置 URL (6)。
- 应用程序的客户端后端从 302 重定向中提取代码和其他参数,并通过对 Salesforce 令牌端点 (
services/oauth2/token) 的请求交换访问令牌的代码 (7)。 - Salesforce 返回带有主题声明中的 UVID 的基于 JWT 的来宾访问令牌 (8)。
- 应用程序的客户端后端处理基于 JWT 的来宾访问令牌并存储 UVID 值,它可以保持专用。它返回来宾会话,并且可选地返回来宾令牌 (9)。
- 应用程序接收令牌响应并创建来宾会话 (10)。
- 以前未知的访问者现在有了与访问令牌中的 UVID 值相关联的来宾会话 (11)。
如专用客户端的步骤 7 中所述,构建服务器端回调处理器,它可以提取 302 重定向并向应用程序返回授权代码。要查看如何构建此处理器,请参阅适用于专用客户端的授权代码和凭据流,其中包含作为 REST 资源公开的示例 Apex 处理器。
未知最终用户到达您的应用程序
该流将在最终用户访问您的应用程序时启动。您还可以将其配置为在用户执行某个操作时启动,例如将商品保存到购物车。
应用程序会在必要时请求 UVID
应用程序尝试从之前对该应用程序的访问中找到 UVID。例如,它确定是否可以从 Cookie 或浏览器的本地存储中提取 UVID。如果应用程序找不到 UVID,它会从其客户端后端请求一个。
客户端后端生成 UVID
提出请求后,客户端后端会生成 UVID 值。Salesforce 不参与生成、存储或维护 UVID。完全取决于您的应用程序。唯一的要求是 UVID 必须是版本 4 通用唯一标识符 (v4 UUID)。
应用程序接收 UVID
应用程序从客户端后端接收 UVID。
应用程序生成 PKCE 参数
如果您正在使用 PKCE,应用程序会生成code_verifier和code_challenge参数。
RFC 7636 中定义的 PKCE 规范还包括您可以在授权请求中发送的可选code_challenge_method参数。Salesforce 忽略您在此参数中发送的任何值,并默认设置为 SHA256。
应用程序将 UVID 交换为授权代码
应用程序向 Experience Cloud 站点上的 Salesforce 授权端点无头发送 GET 或 POST 请求。该请求包含 UVID 和其他参数,用于识别应用程序和指定请求的类型。
您有两个选项选择如何在此请求中发送 UVID。您可以发送普通的 UVID 值,或者发送带有 UVID 的基于 JWT 的访问令牌。例如,如果您在以前的会话中有一个基于 JWT 的访问令牌,那么将该令牌发送到授权端点是重用它的一种简单方法,而不需要专门为 UVID 解析它。
在您的请求中包括这些标题。
| 标题 | 必需? | 描述 |
|---|---|---|
Uvid-Hint
|
如果未在请求正文中发送 UVID,则需要此项。您必须始终包括 UVID - 无论它是在标题中发送还是在请求正文中发送。 | 包含普通值形式的 UVID,或者包含带有 UVID 的基于 JWT 的访问令牌。 如果您将 UVID 作为普通值发送,请在值之前包含 如果您发送带有 UVID 的基于 JWT 的访问令牌,请在值之前包含 |
Auth-Request-Type
|
是。 | 指定您想要向 Salesforce 发送的请求类型。对于无头无密码登录,此值必须设置为 guest。 |
在请求正文中包含这些参数。
| 参数 | 必需? | 描述 |
|---|---|---|
uvid_hint
|
如果不在标题中包含 UVID,则需要此项。 | 包含普通值形式的 UVID,或者包含带有 UVID 的基于 JWT 的访问令牌。 如果您将 UVID 作为普通值发送,请在值之前包含 如果您发送带有 UVID 的基于 JWT 的访问令牌,请在值之前包含 |
client_id
|
是。 | 外部客户端应用程序或连接的应用程序的使用者密钥。 |
response_type
|
是。 | 应用程序请求的 OAuth 2.0 授权类型。因为该流是授权代码和凭据流的变体,所以该值必须是 code_credentials。 |
redirect_uri
|
是。 | 成功身份验证后用户重定向的 URL。 对于专用客户端,使用指向服务器端回调处理器的 |
code_challenge
|
仅当您使用 PKCE 时,这是我们一直推荐的,尤其是对公共客户端。 | 指定令牌请求中 如果授权请求中提供了 如果授权请求中提供了 |
scope
|
是。 | 用于定义应用程序可以访问的受保护资源类型的权限。您在此请求中发送的值必须与分配给外部客户端应用程序或连接的应用程序的范围相匹配,或者是其子集。 有关每个范围及其目的的更多信息,请参阅OAuth 令牌和范围。 |
这些示例授权请求全部实施 PKCE。
下面是一个请求示例,其中 UVID 作为请求标题中的普通值传递。
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
下面是一个请求示例,其中 UVID 在标题的基于 JWT 的访问令牌中传递。
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.MyDomainName.my.site.com/services/apexrest/code/exchange&
code_challenge=********
scope=openid
在此示例中,UVID 在请求正文中作为普通值传递。
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.MyDomainName.my.site.com/services/apexrest/code/exchange&
code_challenge=********
scope=openid
Salesforce 返回 302 重定向
Salesforce 验证 UVID。如果 UVID 作为普通值传递,Salesforce 会验证其格式。如果它作为基于 JWT 的访问令牌传递,Salesforce 将检查令牌的有效性。
然后,Salesforce 将 HTTP 302 重定向返回到包含授权代码的预配置 URL。如果流在浏览器中发生,302 重定向将在浏览器中处理,Salesforce 会自动将重定向响应发送到重定向 URL,该 URL 指向客户端后端的服务器端回调处理器。这是一个预配置 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客户端后端提取代码并将其交换为访问令牌
客户端后端从预配置的 URL 中提取授权码和其他参数。然后,它通过向/services/oauth2/token端点发送无头 POST 请求中的代码和其他参数来启动代码交换。
在请求中包括这些标题。
| 参数 | 必需? | 描述 |
|---|---|---|
Uvid-Hint
|
是。 | 包含普通值形式的 UVID,或者包含带有 UVID 的基于 JWT 的访问令牌。 对于代码交换,请勿包含 UVID 的前缀。例如,如果您将 UVID 作为普通值传递,则标题仅为 |
Auth-Request-Type
|
是。 | 指定您想要向 Salesforce 发送的请求类型。对于无头无密码登录,此值必须设置为 guest。 |
在请求正文中包含这些参数。
| 参数 | 必需? | 描述 |
|---|---|---|
code
|
是。 | 授权服务器创建授权代码,这是一个短期标记,并在成功身份验证后将其传递给客户端。客户端会将授权码发送到授权服务器,以获取访问标记,或刷新标记。 |
client_id
|
是。 | 外部客户端应用程序或连接的应用程序的使用者密钥。 |
client_secret
|
是。 | 外部客户端应用程序或连接的应用程序的使用者密码。 |
redirect_uri
|
是。 | 成功身份验证后用户重定向的 URL。重定向 URI 必须与外部客户端应用程序或连接的应用程序回调 URL 字段中的值之一匹配。否则,批准失败。该值必须是编码 URL。 对于专用客户端,使用指向服务器端回调处理器的 |
grant_type
|
是。 | 应用程序可以提供的验证类型,以证明它是一个安全的访问者。因为该流是授权代码和凭据流的变体,所以值必须是 authorization_code。 |
code_verifier
|
仅当您使用 PKCE 时。 | 指定 128 字节的高熵随机数据,使猜测代码值变得困难。设置此参数有助于防止授权代码拦截攻击。该值必须是 https://datatracker.ietf.org/doc/html/rfc4648#section-5 中定义的 base64url 编码。 如果令牌请求中有 如果令牌请求中包含 |
以下是实施 PKCE 的示例令牌请求。在此示例中,UVID 被作为普通值发送。
POST services/oauth2/token? HTTP 1.1
Host: MyExperienceCloudSite.my.site.com
Auth-Request-Type: guest
Uvid_Hint: abcd-1234-efgh
code=********&
client_id=**********&
client_secret=*********&
redirect_uri=https://www.MyDomainName.my.site.com/services/apexrest/code/exchange&
grant_type=authorization_code&
code_verifier=*******Salesforce 授予基于 JWT 的访问令牌
验证应用程序的凭据后。Salesforce 向客户端后端返回基于 JWT 的来宾访问令牌和状态。来宾访问令牌在主题 (sub) 声明中包含 UVID。以下是基于 JWT 的访问令牌的示例片段。提醒一下,这些令牌有三个组成部分:标题、有效负载和签名。此示例向您显示有效负载。如您所见,sub 声明中的 UVID 值以 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": "**********"
}有关基于 JWT 的访问令牌中每个声明的完整解释,请参阅 Salesforce 帮助中的基于 JWT 的访问令牌。
客户端后端处理访问令牌响应
客户端后端处理访问令牌响应并存储 UVID 值。它会向应用程序返回来宾会话。它还可以返回基于 JWT 的访问令牌,但这不是必需的。
应用程序创建来宾会话
应用程序从其客户端后端接收令牌响应,并创建来宾会话。
现在识别出未知用户
未知最终用户现在有一个与基于 JWT 的访问令牌中返回的 UVID 值相关联的来宾会话。此时,您可自行决定如何处理 UVID。要了解如何将其传递到命名用户授权流,请参见将来宾用户流扩展到命名用户流。

