账号关联¶
当您为已有用户的应用添加社交登录时,部分用户会点击 使用 Google 继续,尽管他们最初是用邮箱和密码注册的。这两种身份使用同一个邮箱地址,但默认情况下,Authany 会把这次 Google 注册当作创建第二个账号的尝试,并以「账号已存在」错误拒绝该请求。
账号关联改变了后续的处理方式。Authany 不再报错,而是检测到新接入的 Google 账号与现有用户匹配,要求用户登录该账号一次以证明所有权,然后将 Google 身份关联到该账号。最终用户只有一个账号,但拥有两种登录方式。
说明
账号关联会在注册过程中自动执行。如果想让已登录的用户通过您自己的界面连接某个提供方,请参阅使用 SDK 关联和取消关联社交/企业登录提供方。用户也可以在用户设置页面管理自己的连接。
何时使用¶
当同一个人可以通过多种注册方式访问您的应用,并且您希望他们始终只保留一个账号时,请启用账号关联。常见场景包括:
- 您为已有密码用户的应用添加了 Google 登录。 使用
alice@example.com和密码注册的用户点击了 使用 Google 继续。他们的 Google 账号使用相同的邮箱。启用账号关联后,用户只需用密码登录一次,此后就可以用任意一种方式登录。 - 您提供了多个社交登录提供方。 用户今天用 Google 注册,下个月又在手机上点击了 使用 Apple 继续。两个账号共用同一个邮箱;账号关联可以让它们合并为一个 Authany 账号,而不是变成两个。
- 您将用户迁移到了 Authany,之后又启用了企业登录提供方。 导入的用户会按邮箱与其 Microsoft Entra ID 或 ADFS 账号匹配,因此他们首次使用企业登录时会关联到您导入的账号,而不会新建一个账号。
工作原理¶
当用户通过社交或企业登录提供方注册时,Authany 会从该提供方的用户资料中读取一个声明(默认是邮箱),并与现有用户的身份进行比对。匹配成功后的处理方式取决于您配置的 action:
| Action | 行为 |
|---|---|
error |
以「重复身份」错误拒绝该次注册。这是未配置账号关联时的默认行为。 |
login_and_link |
向用户展示其现有账号,并要求登录该账号。用户完成身份验证后,将新的提供方身份关联到该账号,并继续完成注册。 |
注意
login_and_link 中的登录步骤可以防止账号被劫持。有些身份提供方允许任何人使用未验证的邮箱注册,因此仅凭邮箱匹配并不能证明所有权。如果没有登录步骤,攻击者就可以在这类提供方上注册 alice@example.com,从而劫持 Alice 的账号。
启用账号关联¶
本教程以 Google 为例,但同样的配置方法适用于您已设置的任何提供方。
前提条件¶
- 已在管理台的 身份验证 > 社交 / 企业登录 中配置好 Google 登录提供方,并设置了别名(alias)。本指南假设别名为
google。如果尚未完成该设置,请参阅将应用连接到 Google。
添加配置¶
在项目的 YAML 配置中配置账号关联。在管理台中进入 高级 > 编辑配置,添加一个 account_linking 部分:
account_linking:
oauth:
- alias: google
oauth_claim:
pointer: "/email"
user_profile:
pointer: "/email"
action: login_and_link
保存配置,更改会立即生效。
account_linking.oauth 下的每一项都定义一条关联规则:
| Field | 含义 |
|---|---|
alias |
该规则适用的提供方。必须与 社交 / 企业登录 中某个提供方的别名一致。 |
oauth_claim |
指向要从接入的提供方资料中读取的声明的 JSON 指针。/email 表示读取 Google 返回的邮箱。 |
user_profile |
指向要与现有用户身份进行匹配的属性的 JSON 指针。/email 表示匹配邮箱登录 ID 或标准属性相同的用户。 |
action |
匹配成功后的处理方式:error 或 login_and_link。 |
说明
oauth_claim 和 user_profile 仅支持 /email、/phone_number 和 /preferred_username。按邮箱匹配适用于 Google 和大多数社交登录提供方;/preferred_username 则适合像 ADFS 这类按用户名识别用户的企业登录提供方。
用户体验到的流程¶
配置好上述内容后,对于已经使用 alice@example.com 拥有密码账号的用户,完整流程如下:
- 用户在注册页面点击 使用 Google 继续,并完成 Google 的授权同意页。
- Authany 找到该现有账号,并展示 找到现有账号 页面,列出经过掩码处理的标识符,例如
al***@example.com。 - 用户选择该账号,并使用现有方式登录,本例中为密码。
- Authany 将 Google 身份关联到该账号。如果您的注册流程要求完成该账号尚未满足的步骤(例如设置双重验证),用户此时需要完成这些步骤;账号已经满足的步骤则会被跳过。
- 用户完成登录。此后,密码和 Google 都可以登录到同一个账号。
关联邮箱、手机号或用户名注册¶
账号关联同样支持反向场景:用户先用 Google 注册,之后又尝试用相同的邮箱地址和密码注册。请在 account_linking.login_id 下配置:
key 用于指定登录 ID 类型(默认为 email、phone 或 username)。当使用该登录 ID 注册的请求与现有用户匹配时,用户会登录到现有账号(本例中通过 Google 登录),新的邮箱登录 ID 会被添加到该账号。如果不做此配置,冲突的注册请求会像之前一样以错误失败。
进阶:为不同注册流程设置不同规则¶
如果您定义了自定义身份验证流程,可以在特定的注册流程步骤中覆盖某条关联规则。先在 account_linking 中为规则设置一个 name,再在该步骤中引用这个名称,以覆盖其 action 或指定由哪个登录流程来处理登录:
account_linking:
oauth:
- name: google_linking
alias: google
oauth_claim:
pointer: "/email"
user_profile:
pointer: "/email"
action: error
authentication_flow:
signup_flows:
- name: customer_signup
steps:
- name: identify
type: identify
one_of:
- identification: oauth
account_linking:
oauth:
- name: google_linking
action: login_and_link
login_flow: customer_login
在此示例中,除 customer_signup 流程外,Google 关联在其他任何地方都会以错误失败;该流程允许关联,并在登录步骤中运行 customer_login 流程。如果未设置 login_flow,Authany 会使用与当前注册流程同名的登录流程。
自定义界面中的账号关联¶
如果您使用身份验证流程 API构建自己的注册界面,账号关联会表现为一个 identify 动作,其 data.type 为 account_linking_identification_data。数据中包含匹配到的账号列表及其经过掩码处理的显示名称;您的界面需要提交用户所选账号的索引,随后流程会继续进入登录步骤。具体的数据结构请参阅身份验证流程 API 参考。