通过 OAuth 和“使用 Google 账号登录”简化关联流程

概览

基于 OAuth 的“使用 Google 账号登录”简化版关联OAuth 关联的基础上添加了“使用 Google 账号登录”。这样一来,Google 用户便可顺畅地关联账号,同时还能创建账号,让用户可以使用自己的 Google 账号在您的服务中创建新账号。

如需使用 OAuth 和“使用 Google 账号登录”功能执行账号关联,请按以下常规步骤操作:

  1. 首先,征求用户同意以访问其 Google 个人资料。
  2. 使用用户个人资料中的信息检查用户账号是否存在。
  3. 对于现有用户,请关联账号。
  4. 如果您在身份验证系统中找不到与 Google 用户匹配的用户,请验证从 Google 收到的 ID 令牌。然后,您可以根据 ID 令牌中包含的个人资料信息创建用户。
此图显示了用户使用简化的关联流程关联其 Google 账号的步骤。第一张屏幕截图显示了用户如何选择您的应用以进行关联。第二个屏幕截图可让用户确认他们是否在您的服务中拥有现有账号。第三张屏幕截图显示了用户可以选择要关联的 Google 账号。第四张屏幕截图显示了将用户的 Google 账号与您的应用相关联的确认信息。第五张屏幕截图显示了 Google 应用中成功关联的用户账号。
在用户手机上通过精简关联功能关联账号

图 1. 在用户手机上使用精简的关联方式进行账号关联

简化的关联:OAuth +“使用 Google 账号登录”流程

以下序列图详细说明了用户、Google 和您的令牌交换端点之间针对简化关联的互动。

用户 Google 应用 / 服务器 您的令牌 交换端点 您的 API 1. 用户发起关联 2. 请求使用 Google 账号登录 3. 使用 Google 账号登录 4. 检查 intent (JWT 断言) 5. account_found:true/false 如果找到账号 6. 获取 intent 如果没有账号 6. 创建 intent 7. access_token、refresh_token 8. 存储用户令牌 9. 访问用户资源
图 2. 简化版关联流程中的事件序列。

角色和职责

下表定义了简化版关联流程中各个参与者的角色和职责。

执行者 / 组件 GAL 角色 职责
Google 应用 / 服务器 OAuth 客户端 获取用户对“使用 Google 账号登录”的同意情况,将身份断言 (JWT) 传递给您的服务器,并安全地存储生成的令牌。
您的令牌交换端点 身份提供方 / 授权服务器 验证身份断言,检查是否存在现有账号,处理账号关联 intent(checkgetcreate),并根据请求的 intent 签发令牌。
您的服务 API 资源服务器 在提供有效的访问令牌时,提供对用户数据的访问权限。

简化版关联的要求

简化关联的决策逻辑

以下逻辑决定了在简化的关联流程中如何调用 intent:

  1. 用户在您的身份验证系统中是否有账号?(用户通过选择“是”或“否”来决定)
    1. 是:用户是否使用与 Google 账号关联的电子邮件地址登录您的平台?(用户通过选择“是”或“否”来决定)
      1. 是:用户在您的身份验证系统中是否有匹配的账号?(调用 check intent 以进行确认)
        1. YES:调用 get intent,如果获取 intent 成功返回,则关联账号。
        2. 否:创建新账号?(用户通过选择“是”或“否”来决定)
          1. 是:调用 create intent,如果创建 intent 成功返回,则关联账号。
          2. 否:系统会触发 OAuth 关联流程,将用户定向到其浏览器,并为用户提供与其他电子邮件地址关联的选项。
      2. 否:系统会触发 OAuth 关联流程,将用户定向到其浏览器,并让用户选择是否关联其他电子邮件地址。
    2. 否:用户在您的身份验证系统中是否有匹配的账号?(调用 check intent 以进行确认)
      1. YES:调用 get intent,如果获取 intent 成功返回,则关联账号。
      2. 否:如果创建 intent 成功返回,则会调用 create intent 并关联账号。

实施方案

您的令牌交换端点必须实现 checkgetcreate intent,才能支持精简关联。

请按照以下步骤处理不同的 intent:

检查现有用户账号(检查 intent)

Google 会调用您的令牌交换端点,以验证 Google 用户是否存在于您的系统中。如需了解参数详情,请参阅简化的关联 intent

实现方案

如需处理 check intent,请执行以下操作:

  1. 验证请求

    • 验证 client_idclient_secretgrant_type(必须为 urn:ietf:params:oauth:grant-type:jwt-bearer)。
    • 使用 JWT 验证 中的条件验证 assertion (JWT)。
  2. 查找用户

    • 检查 JWT 中的 Google 账号 ID (sub) 或电子邮件地址是否与数据库中的用户匹配。
  3. 回应

    • 如果找到:返回 HTTP 200 OK,并附带 {"account_found": "true"}
    • 如果未找到:返回 HTTP 404 Not Found,并附带 {"account_found": "false"}

处理自动关联(获取 intent)

如果该账号存在,Google 会使用 intent=get 调用您的端点以检索令牌。如需了解参数详情,请参阅简化的关联 intent

实施方案

如需处理 get intent,请执行以下操作:

  1. 验证请求

    • 验证 client_idclient_secretgrant_type
    • 验证 assertion (JWT)。
  2. 查找用户

    • 使用 subemail 声明验证用户是否存在。
  3. 回应

    • 如果成功:在 JSON 响应 (HTTP 200 OK) 中生成并返回 access_tokenrefresh_tokenexpires_in
    • 如果关联失败:返回 HTTP 401 Unauthorized,其中包含 {"error": "linking_error"} 和可选的 login_hint,以便回退到标准 OAuth 关联。

使用“使用 Google 账号登录”功能处理账号创建事宜(创建 intent)

如果不存在任何账号,Google 会使用 intent=create 调用您的端点,以创建新用户。如需了解参数详情,请参阅 Streamlined Linking Intents

实现方案

如需处理 create intent,请执行以下操作:

  1. 验证请求

    • 验证 client_idclient_secretgrant_type
    • 验证 assertion (JWT)。
  2. 验证用户不存在

    • 检查您的数据库中是否已存在 subemail
    • 如果用户 存在,请返回 HTTP 401 Unauthorized,并使用 {"error": "linking_error", "login_hint": "USER_EMAIL"} 强制回退到 OAuth 关联。
  3. 创建账号

    • 使用 JWT 中的 subemailnamepicture 声明创建新的用户记录。
  4. 回应

    • 在 JSON 响应 (HTTP 200 OK) 中生成并返回令牌。

获取 Google API 客户端 ID

在账号关联注册过程中,您需要提供 Google API 客户端 ID。使用您在完成 OAuth 关联步骤时创建的项目获取 API 客户端 ID。为此,请完成以下步骤:

  1. 前往“客户”页面
  2. 创建或选择 Google APIs 项目。

    如果您的项目没有 Web 应用类型的客户端 ID,请点击创建客户端进行创建。请务必在已获授权的 JavaScript 来源框中添加您网站的域名。在执行本地测试或开发时,您必须将 http://localhosthttp://localhost:<port_number> 都添加到已获授权的 JavaScript 来源字段中。

验证您的实现效果

您可以使用 OAuth 2.0 Playground 工具验证您的实现。

在该工具中,执行以下步骤:

  1. 点击配置 以打开“OAuth 2.0 配置”窗口。
  2. OAuth flow(OAuth 流程)字段中,选择 Client-side(客户端)。
  3. OAuth Endpoints 字段中,选择 Custom
  4. 在相应字段中指定您的 OAuth 2.0 端点以及您分配给 Google 的客户端 ID。
  5. 第 1 步部分中,请勿选择任何 Google 范围。请将此字段留空,或输入适用于您服务器的范围(如果您不使用 OAuth 范围,则输入任意字符串)。完成后,点击 Authorize APIs
  6. 第 2 步第 3 步部分中,完成 OAuth 2.0 流程,并验证每个步骤是否按预期运行。

您可以使用 Google 账号关联演示工具验证您的实现。

在该工具中,执行以下步骤:

  1. 点击使用 Google 账号登录按钮。
  2. 选择您要关联的账号。
  3. 输入服务 ID。
  4. (可选)输入您将请求访问的一个或多个范围。
  5. 点击开始演示
  6. 当系统提示时,请确认您可以同意或拒绝关联请求。
  7. 确认您已重定向到相应平台。