无头身份 API:专用客户端的无头注册流
对于能够保留机密信息的应用程序,例如具有客户端-服务器架构的 Web 应用程序,您可以使用无头注册流为客户和合作伙伴设置无头注册。无头注册流扩展了授权代码和凭据流,该流构建于 OAuth 2.0 授权代码授权类型。使用此流,您可以在第三方应用程序中控制前端用户注册体验。您可以通过 Experience Cloud 站点调用 Salesforce 无头注册 API,以创建用户、登录并授予用户对 Salesforce 资源的访问权限。通过分离这两个流程,用户可以注册您的应用程序并访问 Salesforce 数据,而无需离开应用程序。
所需的 Edition
| 适用于:Salesforce Classic(并非在所有组织中可用)和 Lightning Experience |
| 适用于:Enterprise、Unlimited 和 Developer Edition |
以下是无头注册流的用例示例。您在一家旅游公司工作,该公司在 Salesforce 中管理客户信息。对应用程序中的用户体验具有完整控制权限非常重要。您还希望通过鼓励客户注册您的应用程序来留住更多客户,这需要身份服务。因为您的公司已经使用 Salesforce,所以无头身份是前进的方法。您可以构建传统客户端-服务器应用程序,并配置无头注册流。当新用户注册您的应用程序时,他们会看到您的自定义注册体验。他们注册、验证其身份并访问 Salesforce 数据,而无需直接与 Salesforce 交互。
要扩展在流期间发送给最终用户的一次性密码 (OTP) 电子邮件的电子邮件模板选项,请选择电子邮件模板允许列表并使用自定义模板创建允许列表。请参阅为无头流使用多个电子邮件模板。
在设置此流之前,请在连接的应用程序或外部客户端应用程序上配置必要的设置和访问策略,请参阅为授权代码和凭据流配置连接的应用程序或为授权代码和凭据流配置外部客户端应用程序
以下是流的概述。
- 用户打开您的应用程序并单击“注册”。(1)
- 在您的应用程序中,您可以在本机显示注册表单来收集用户数据。您可以设计该表单并自定义您想要收集的信息。(2)
- 用户在应用程序中输入信息。例如,他们输入新用户名、密码和名字。(3)
- 您的应用程序向 Experience Cloud 站点上的无头注册 API /services/auth/headless/init/registration 端点提交用户信息。(4)
- Salesforce 收到用户信息,并将其加入队列以稍后处理。Salesforce 向您的应用程序返回包含注册请求 ID 的成功消息。(5a)
- 然后,Salesforce 会向用户发送一封包含一次性密码 (OTP) 的电子邮件或短信。(5b)
- 在应用程序中,您将在本机显示 OTP 验证表单。您可以选择希望该表单使用的外观。(6)
- 用户收到 OTP,并在验证表单中输入。(7)
- 然后,您的应用程序使用对无头登录 API 的授权代码请求来初始化授权代码和凭据流。请求包括 OTP 和请求 ID,以及其他参数。(8)
- Salesforce 验证请求 ID 和 OTP。它检索之前存储的排队用户数据,并调用无头注册处理器。无头注册处理器会在 Salesforce 中创建用户。(9)
- Salesforce 将 302 重定向返回到包含授权代码的预配置 URL。302 重定向在浏览器中处理,响应被无头地传递给服务器上预先配置的回调处理器。(10)
- 服务器端回调处理器会从 302 重定向中提取代码和其他参数。然后,通过令牌端点的 POST 请求,启动代码交换。(11)
- 从令牌端点中,Salesforce 向服务器端回调处理器返回访问令牌响应。(12)
- 服务器端回调处理器处理令牌响应,并向应用程序返回登录状态。该响应可能包括会话详细信息、用户信息,还可能包括访问令牌,具体取决于您的应用程序设计和安全状况。(13)
- 浏览器会收到登录响应,并创建用户会话。(14)
- 用户现在已登录,他们在您的自定义应用程序中执行操作,启动对 Salesforce 数据的请求。例如,他们单击按钮访问存储在 Salesforce Experience Cloud 站点中的旅行预订历史记录。(15)
- 自定义应用程序向受保护的 Salesforce 端点发送验证请求,例如 Salesforce API。(16)
- 客户现在可以在自定义应用程序中访问他们受保护的数据。例如,他们可以看到他们的旅行预订历史。(17)
用户打开第三方应用程序并单击注册
用户打开您的应用程序并单击注册链接,或者单击链接访问需要注册的资源。
应用程序显示注册表单
在您的应用程序中,您可以在本机显示注册表单来收集用户数据。您可以控制有关此表单的全部内容,包括外观、感觉,以及您想要收集的用户信息。
关于您想从用户那里收集什么信息,有几个考虑因素。应用程序向无头注册 API 提交用户信息时,Salesforce 会检查电子邮件地址、用户名、姓氏和密码。您可以从用户那里收集这些信息或自动生成,但必须包含在 POST 请求中。在决定要包含哪些信息时,请确保收集电子邮件地址或电话号码,以便用户可以验证身份。
用户输入信息
在您的应用程序中,用户在注册表单中输入信息。
应用程序会将用户信息无头发送到无头注册 API
从浏览器中,您的应用程序会使用异步 Java 和 XML (AJAX) 向 Experience Cloud 站点上的无头注册端点发送 POST 请求 (/services/auth/headless/init/registration)。
在您的注册请求中包括这些标题。
| 页眉 | 必需? | 描述 |
|---|---|---|
Authorization: Bearer
|
如果您在 Experience Cloud 登录和注册页面上启用需要身份验证才能访问此 API,则需要此标题。我们强烈建议您为专用客户端启用此设置。 | 包含向内部集成用户颁发的访问令牌。要获取访问令牌,您可以使用 Salesforce 支持的任何标准 OAuth 流。请确保将user_registration_api范围分配给连接的应用程序或外部客户端应用程序,或在流期间将其作为参数传递。 |
Content-Type
|
否。如果您使用 Postman 构建和测试流,有时会添加此标题。通过检查隐藏的标题,验证它是否正确。 | 指定请求的格式,例如application/json。 |
在请求正文中包含这些参数。
| 参数 | 必需? | 描述 |
|---|---|---|
password
|
是。 | 用户密码。密码受到为简档或组织配置的任何密码策略的约束。 |
userdata
|
是。即使您没有从用户那里收集这些信息,也必须自动生成并在 userdata 参数中传递它。 |
包含所有必需的用户信息。Salesforce 至少会在
|
recaptcha
|
如果这些条件对您适用,将是必填项。
|
当用户完成 reCAPTCHA 质询时,由 Google reCAPTCHA API 颁发的加密令牌。 |
recaptchaevent
|
如果这些条件适用于您,则需要:
|
包含这些子参数的 JSON 对象。
有关更多信息,请查看 Google reCAPTCHA 文档。 |
verificationmethod
|
否。如果您不包括此参数,Salesforce 会默认使用电子邮件验证用户身份。 如果您包含此参数,请在对授权端点的请求中包含 |
用于验证用户身份的方法。Salesforce 支持验证方法的两个值:email 和 sms。 |
customdata
|
否。 | 包含您收集的任何自定义用户信息。例如,您可以包含用户的街道地址。 |
emailtemplate
|
如果启用电子邮件模板允许列表,需要指定多个电子邮件模板。 如果没有启用电子邮件模板允许列表,则不能包含此参数。 如果不包含此参数,Salesforce 会使用在 Experience Cloud 设置中配置的默认电子邮件模板,而不管是否启用了允许列表。如果没有配置模板,Salesforce 将使用默认 OTP 电子邮件模板。 |
自定义电子邮件模板开发人员名称。此参数只能包含来自允许列表的电子邮件模板。 |
以下是 POST 请求示例。在此示例中,Experience Cloud 设置被配置为需要身份验证和 reCAPTCHA,因此请求会包括访问令牌和 reCAPTCHA 令牌。
POST /services/auth/headless/init/registration? HTTP 1.1
Host: MyDomainName.my.site.com
Content-Type: application/json
Authorization: Bearer **************
{
“userdata”: {
“firstName”: “Janice”
“lastName”: “Edwards”
“email”: “janice.edwards@example.com”
“username”: “jedwards@myapp.com”
}
“customdata”: {
{”mobilePhone”=”<mobile phone number>”
}
“password”: “*******”
“recaptcha”:”***********”
“verificationmethod”: “email”
“emailtemplate”: “unfiled$public/SalesNewCustomerEmail”
}Salesforce 接收信息并返回请求标识符
Salesforce 会收到用户信息。因为 Salesforce 尚未验证用户的身份,所以它会将此信息排队以待以后处理。
如果 POST 请求中的信息有效,Salesforce 会向应用程序返回成功消息。该消息包括注册请求标识符,这在流的后面很重要。以下是成功消息示例。
{
"status": "success",
"email": “jedwards@myapp.com”
"identifier": “0RXXXXXXXX”
}Salesforce 向用户发送一次性密码
Salesforce 收到用户数据并向应用程序发送成功消息后,会立即通过电子邮件或短信发送一次性密码 (OTP),具体取决于用户的验证方法。
应用程序在本机显示验证表单
收到成功消息时,您会在应用程序中本机显示 OTP 验证表单。同样,验证体验的外观完全取决于您。
用户在验证表单中输入 OTP
用户通过电子邮件或短信收到 OTP,并在验证表单中输入。
应用程序初始化授权代码和凭据流
当用户证明他们的身份时,应用程序立即初始化授权代码和凭据流,并向无头登录 API 发出请求。
在授权请求中包含这些标题
| 页眉 | 必需? | 描述 |
|---|---|---|
Auth-Request-Type
|
是。 | 指定您想要向 Salesforce 发送的请求类型。对于无头注册,此值必须设置为 user-registration。 |
Authorization
|
是。 | 标识注册请求的基本标题,以便 Salesforce 可以将请求链接到用户存储的数据。您必须包括 Salesforce 提供的请求标识符和用于验证用户身份的 OTP。 以 |
Content-Type
|
否。如果您使用 Postman 构建和测试流,有时会添加此标题。通过检查隐藏的标题,验证它是否正确。 | 指定请求的格式,例如application/x-www-form-urlencoded。 |
Auth-Verification-Type
|
如果您在初始注册请求中指定了身份验证方法,则需要此项。此标题的值必须与从请求到/services/auth/headless/init/registration端点的verificationmethod正文参数中的值相匹配。 |
指定用于验证用户身份的方法。Salesforce 支持验证方法的两个值:email 和 sms。 |
Uvid-Hint
|
否。如果您在应用程序中实施来宾用户流,您可以选择使用该标题来传入基于 JSON Web 令牌 (JWT)的访问令牌,其中包含一个与来宾用户身份相关联的唯一访问者 ID (UVID)。通过将 UVID 传递给命名用户流,您可以将来自来宾用户会话的上下文信息(例如用户的 Cookie 首选项)传递给命名用户会话。 您也可以在请求正文中传递普通的 UVID 值,而不是在标题中传递带有 UVID 的基于 JWT 的令牌。 |
基于 JWT 的访问令牌,包含 UVID 值,这是一个版本 4 通用唯一标识符 (UUID),完全由您的应用程序生成和管理。要获得带有 UVID 的访问令牌,您必须使连接的应用程序或外部客户端应用程序能够发布基于 JWT 的访问令牌,并在您的应用程序上实施无头来宾流。 |
在请求正文中包含这些参数。
| 参数 | 必需? | 描述 |
|---|---|---|
client_id
|
是。 | 连接的应用程序或外部客户端应用程序的使用者密码。 |
response_type
|
是。 | 连接的应用程序或外部客户端应用程序请求的 OAuth 2.0 授权类型。对于授权代码和凭据流,值必须code_credentials。 |
redirect_uri
|
是。 | 成功身份验证后用户重定向的 URL。重定向 URI 必须与连接的应用程序或外部客户端应用程序回调 URL 字段中的值之一匹配。否则,批准失败。该值必须是编码 URL。 |
uvid_hint
|
否。如果您在应用程序上实施来宾用户流,您可以选择使用此参数传入与来宾用户身份相关的 UVID 值,将来自来宾用户会话的上下文信息传送到命名用户会话中。 您还可以通过 |
普通 UVID 值,即应用程序生成和管理的版本 4 UUID。要获得 UVID,您必须使连接的应用程序或外部客户端应用程序能够发布基于 JWT 的访问令牌,并在您的应用程序上实施无头来宾流。 |
code_challenge
|
仅当您使用 PKCE 时。 | 如果使用 PKCE 扩展,是必填项。指定令牌请求中 如果在令牌请求中指定了
|
以下是无头登录 API 的示例请求,包括 PKCE。
POST /services/oauth2/authorize? HTTP 1.1
Host: MyDomainName.my.site.com
Auth-Request-Type: user-registration
Auth-Verification-Type: email
Content-Type: application/x-www-form-urlencoded
Authorization: Basic <base64-encoded request ID:OTP>
response_type=code_credentials&
client_id=******&
redirect_uri=https://www.MyDomainName.my.site.com/services/apexrest/code/exchange&
code_challenge=Y29kZ*******
Salesforce 验证请求、检索用户数据并创建用户
Salesforce 接收授权请求,并验证请求 ID 和 OTP。Salesforce 使用此信息检索已排队的用户数据并调用在 Experience Cloud 站点中配置的无头注册处理器。Apex 处理器在 Salesforce 中创建用户,并将其链接到客户。
Salesforce 将 302 重定向返回到包含代码的预配置 URL
Salesforce 将 HTTP 302 重定向返回到包含授权代码的预配置 URL。302 重定向在浏览器中处理,响应被无头地传递到重定向 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回调处理器提取代码并执行代码交换
服务器端回调处理器从 302 重定向中提取授权代码和其他参数。然后,通过向令牌端点发送无头 POST 请求,启动代码交换。
对于访问令牌请求,您只能使用 POST 请求 — 不支持 GET 请求。此请求没有必填标题,但您可以包含Content-Type标题。
| 标题 | 必需? | 描述 |
|---|---|---|
Content-Type
|
否。如果您使用 Postman 构建和测试流,有时会添加此标题。通过检查隐藏的标题,验证它是否正确。 | 指定请求的格式,例如application/x-www-form-urlencoded。 |
在请求正文中包含这些参数。
| 参数 | 必需? | 描述 |
|---|---|---|
client_id
|
是。 | 连接的应用程序或外部客户端应用程序的使用者密钥。 |
client_secret
|
是。 | 连接的应用程序或外部客户端应用程序的使用者密码。 |
code
|
是。 | 授权服务器创建授权代码,这是一个短期标记,并在成功身份验证后将其传递给客户端。客户端会将授权码发送到授权服务器,以获取访问标记,或刷新标记。 |
code_verifier
|
如果使用 PKCE 扩展,是必填项。 | 指定 128 字节的高熵随机数据,使猜测
|
format
|
否。 | 响应的预期格式。Salesforce 支持这些格式。
|
grant_type
|
是。 | 连接的应用程序或外部客户端应用程序可以提供的验证类型,以证明它是一个安全的访问者。对于授权代码和凭据流,值必须是 authorization_code。 |
redirect_uri
|
是。 | 成功身份验证后用户重定向的 URL。重定向 URI 必须与连接的应用程序或外部客户端应用程序回调 URL 字段中的值之一匹配。该值必须是编码 URL。 |
以下是令牌请求示例。
POST /services/oauth2/token HTTP 1.1
Host: MyDomainName.my.site.com
Content-Type: application/x-www-form-urlencoded
grant_type=authorization_code&
code=aPrxC1*******&
client_id=******&
client_secret=******&
redirect_uri=https://www.MyExperienceCloudSite.my.site.com/services/apexrest/code/exchange&
code_verifier=Y29kZ*******
Salesforce 授予访问标记
Salesforce 验证令牌请求,并向服务器端回调处理器返回访问令牌响应。以下是 JSON 格式的访问标记响应示例。
{
"access_token":"*******************",
"sfdc_community_url":"https://MyDomainName.my.site.com",
"sfdc_community_id":"0DBxxxxxxxxxxxx",
"signature":"ts6wm/svX3jXlCGR4uu+SbA04M6qhD1SAgVTEwZ59P4=",
"scope":"openid api",
"id_token":"XXXXXX",
"instance_url":"https://yourInstance.salesforce.com",
"id":"https://yourInstance.salesforce.com/id/00Dxxxxxxxxxxxx/005xxxxxxxxxxxx",
"token_type":"Bearer",
"issued_at":"1667600739962"
}访问标记响应包含这些参数。
| 参数 | 必需? | 描述 |
|---|---|---|
access_token
|
是。 | 连接的应用程序或外部客户端应用程序用来代表客户端应用程序请求访问受保护资源的 OAuth 标记。访问标记可以附带范围形式的附加权限。 |
id
|
是。 | 可用于标识用户以及查询有关用户的更多信息的身份 URL。请参阅身份 URL。 |
id_token
|
否。 | |
instance_url
|
是。 | 指示用户的组织实例的 URL。例如:https://yourInstance.salesforce.com/. |
issued_at
|
是。 | 创建签名的时间戳,以自 UTC 时间 1970-01-01T0:0:0Z 起的毫秒数表示。 |
refresh_token
|
否。 | 从 Web 服务器、用户代理或混合应用程序标记流中获取的标记。该值是密钥。采取适当措施保护它。仅当您连接的应用程序或外部客户端应用程序设置了refresh_token范围时,才会返回此参数。 |
signature
|
是。 | 使用 client_secret 签名的 Base64 编码 HMAC-SHA256 签名。签名可以包括连接 ID 和issued_at value,您可以使用它们来验证身份 URL 在服务器发送后没有更改。 |
sfdc_community_url
|
是。 | Experience Cloud 站点的 URL。 |
sfdc_community_id
|
是。 | 用户的 Experience Cloud 站点 ID。 |
state
|
否。 | 客户端请求的状态。仅当原始查询字符串中包含 state 参数时,才会包含此值。 |
token_type
|
是。 | Bearer标记类型,用于包含访问标记的所有响应。 |
回调处理器处理令牌响应并将参数返回给应用程序
服务器端回调处理器从响应中获取访问令牌。服务器端回调处理器然后向浏览器返回访问令牌和状态,以及用户数据、令牌和会话数据。作为最佳实践,我们建议您配置服务器以存储访问令牌,为应用程序创建会话,并将会话返回到应用程序,而不是返回访问令牌。作为开发人员,您拥有创建会话、存储访问令牌和管理登录状态的完全控制,因此您的具体实施取决于您。
以下是浏览器控制台日志中成功响应的示例。
{"success":true,"state":"https://MyExperienceCloudSite.my.site.com/","errMsg":null,"access_token":"00*******"}应用程序处理令牌响应并创建用户会话
应用程序会收到令牌响应,处理它,并创建用户会话。
用户已注册,并在应用程序中执行操作
用户现在已经注册并登录。他们在您的应用程序中执行需要访问 Salesforce 数据的操作。例如,他们单击按钮来查看他们的旅行预订历史,该历史存储在 Salesforce 中。
应用程序对 Salesforce 端点进行身份验证调用
要访问用户的 Salesforce 数据,您的应用程序使用访问标记对受保护的 Salesforce 端点进行身份验证调用,例如 Salesforce API。
用户可以访问 Salesforce 数据
用户现在可以在您的应用程序中访问受保护的 Salesforce 数据。例如,他们可以看到他们的旅行预订历史。

