用户数据结构
用户是身份服务中的核心实体。在 Logto 中,它们包括基于 OpenID Connect 协议的基本认证 (Authentication) 数据,以及自定义数据。
用户资料
每个用户都有一个包含所有用户信息的资料。
它由以下类型的数据组成:
- 基本数据:来自用户资料的基本信息。它存储所有其他 用户 的属性,除了社交
identities
和custom_data
,例如用户 ID、用户名、电子邮件、电话号码以及用户上次登录的时间。 - 社交身份:存储从社交登录(即使用社交连接器登录)中获取的用户信息,例如 Facebook、GitHub 和微信。
- 自定义数据:存储未列在预定义用户属性中的其他用户信息,例如用户偏好的颜色和语言。
以下是从 Facebook 登录中获取的用户数据示例:
{
"id": "iHXPuSb9eMzt",
"username": null,
"primaryEmail": null,
"primaryPhone": null,
"name": "John Doe",
"avatar": "https://example.com/avatar.png",
"customData": {
"preferences": {
"language": "en",
"color": "#f236c9"
}
},
"identities": {
"facebook": {
"userId": "106077000000000",
"details": {
"id": "106077000000000",
"name": "John Doe",
"email": "[email protected]",
"avatar": "https://example.com/avatar.png"
}
}
},
"lastSignInAt": 1655799453171,
"applicationId": "admin_console"
}
你可以使用 Logto Console 或 Logto Management API 查询用户资料,例如 GET /api/users/:userId
。
基本数据
让我们逐步了解用户 基本数据 中的所有属性。
id
id 是一个唯一的自动生成的键,用于在 Logto 中标识用户。
username
username 用于使用 username 和密码登录。
其值来自用户首次注册时的用户名。它可能为 null
。其非空值不应超过 128 个字符,只能包含字母、数字和下划线 (_
),且不能以数字开头。它是区分大小写的。
primary_email
primary_email 是用户的电子邮件地址,用于使用电子邮件和密码 / 验证码登录。
其值通常来自用户首次注册时的电子邮件地址。它可能为 null
。其最大长度为 128。
primary_phone
primary_phone 是用户的电话号码,用于使用电话号码和密码 / 短信验证码登录。
其值通常来自用户首次注册时的电话号码。它可能为 null
。其非空值应包含以 国家区号(不包括加号 +
)为前缀的数字。
name
name 是用户的全名。其最大长度为 128。
avatar
avatar 是指向用户头像图片的 URL。其最大长度为 2048。
如果用户使用像 Google 和 Facebook 这样的社交连接器注册,其值可能会从社交用户信息中获取。
此属性映射到 OpenID Connect 标准中的 picture
声明。
profile
profile 存储其他未包含在用户属性中的 OpenID Connect 标准声明。
其类型定义可以在 此文件 中找到。以下是类型定义的副本:
type UserProfile = Partial<{
familyName: string;
givenName: string;
middleName: string;
nickname: string;
preferredUsername: string;
profile: string;
website: string;
gender: string;
birthdate: string;
zoneinfo: string;
locale: string;
address: Partial<{
formatted: string;
streetAddress: string;
locality: string;
region: string;
postalCode: string;
country: string;
}>;
}>;
Partial
意味着所有属性都是可选的。
与其他标准声明相比的一个区别是,profile
中的属性只有在其值不为空时才会包含在 ID 令牌 或用户信息端点响应中,而其他标准声明如果值为空将返回 null
。
application_id
application_id 的值来自用户首次登录的应用程序。它可能为 null
。
last_signed_in_at
last_signed_in_at 是用户上次登录时带有时区的时间戳。
password_encrypted
password_encrypted 用于存储用户的加密密码。
其值来自用户首次注册时的密码。它可能为 null
。如果其值为非空,则加密前的原始内容应至少为六个字符。
password_encryption_method
password_encryption_method 用于加密用户的密码。其值在用户使用用户名和密码注册时初始化。它可能为 null
。
Logto 默认使用 Argon2 的实现 node-argon2 作为加密方法;如果你感兴趣,请参阅参考资料以获取详细信息。
从密码为 123456
的用户中抽样一个 password_encrypted 和 password_encryption_method:
{
"password_encryption_method": "Argon2i",
"password_encrypted": "$argon2i$v=19$m=4096,t=10,p=1$aZzrqpSX45DOo+9uEW6XVw$O4MdirF0mtuWWWz68eyNAt2u1FzzV3m3g00oIxmEr0U"
}
is_suspended
is_suspended 是一个布尔值,指示用户是否被暂停。可以通过调用 Logto Management API 或使用 Logto Console 来管理该值。
一旦用户被暂停,预先授予的刷新令牌将立即被撤销,用户将无法再通过 Logto 进行认证 (Authentication)。
属性参考
以下属性(除 password_encrypted 和 password_encryption_method 外)在用户资料上可见,这意味着你可以使用 Management API 查询它们。
名称 | 类型 | 描述 | 唯一 | 必需 |
---|---|---|---|---|
id | string | 唯一标识符 | ✅ | ✅ |
username | string | 登录用的用户名 | ✅ | ❌ |
primary_email | string | 主电子邮件 | ✅ | ❌ |
primary_phone | string | 主电话号码 | ✅ | ❌ |
name | string | 全名 | ❌ | ❌ |
avatar | string | 指向用户头像图片的 URL | ❌ | ❌ |
identities | object | 从社交登录中获取的用户信息 | ❌ | ✅ |
custom_data | object | 可自定义属性中的附加信息 | ❌ | ✅ |
application_id | string | 用户首次注册的应用程序 ID | ❌ | ✅ |
last_sign_in_at | date time | 用户上次登录的时间戳 | ❌ | ✅ |
password_encrypted | string | 加密密码 | ❌ | ❌ |
password_encryption_method | string | 密码加密方法 | ❌ | ❌ |
is_suspended | bool | 用户暂停标记 | ❌ | ✅ |
- 唯一:确保输入到数据库表属性中的值的唯一性。
- 必需:确保输入到数据库表属性中的值不能为
null
。
社交身份
identities 包含从社交登录(即使用社交连接器登录)中获取的用户信息。每个用户的 identities 存储在一个单独的 JSON 对象中。
用户信息因社交身份提供商(即社交网络平台)而异,通常包括以下内容:
- 身份提供商的 target,例如 "facebook" 或 "google"
- 用户在此提供商的唯一标识符
- 用户的姓名
- 用户的已验证电子邮件
- 用户的头像
用户的账户可以通过社交登录链接到多个社交身份提供商;从这些提供商获取的相应用户信息将存储在 identities 对象中。
从同时使用 Google 和 Facebook 登录的用户中抽样 identities:
{
"facebook": {
"userId": "5110888888888888",
"details": {
"id": "5110888888888888",
"name": "John Doe",
"email": "[email protected]",
"avatar": "https://example.com/avatar.png"
}
},
"google": {
"userId": "111000000000000000000",
"details": {
"id": "111000000000000000000",
"name": "John Doe",
"email": "[email protected]",
"avatar": "https://example.com/avatar.png"
}
}
}
自定义数据
custom_data 存储未列在预定义用户属性中的其他用户信息。
你可以使用 custom_data 做以下事情:
- 记录用户是否完成了特定操作,例如是否已查看欢迎页面。
- 在用户资料中存储应用程序特定的数据,例如用户每个应用程序的首选语言和外观。
- 维护与用户相关的其他任意数据。
从 Logto 中的管理员用户中抽样 custom_data:
{
"adminConsolePreferences": {
"language": "en",
"appearanceMode": "system",
"experienceNoticeConfirmed": true
},
"customDataFoo": {
"foo": "foo"
},
"customDataBar": {
"bar": "bar"
}
}
每个用户的 custom_data 存储在一个单独的 JSON 对象中。
注意:不要在 custom_data 中放置敏感数据。
你可以使用 Management API 获取包含 custom_data 的用户资料,并将其发送到前端应用程序或外部后端服务。因此,将敏感信息放在 custom_data 中可能会导致数据泄露。
如果你仍然想将敏感信息放在 custom_data 中,我们建议先加密它。仅在受信任的方(如你的后端服务)中进行加密 / 解密,避免在前端应用程序中进行。这将最大限度地减少如果用户的 custom_data 被错误泄露时的损失。
你可以使用 Logto Console 或 Logto Management API 更新用户的 custom_data,例如 PATCH /api/users/:userId
。
谨慎更新
更新用户的 custom_data 将完全覆盖其存储中的原始内容。
例如,如果你调用更新 custom_data API 的输入如下(假设原始 custom_data 是之前显示的示例数据):
{
"customDataBaz": {
"baz": "baz"
}
}
那么更新后的 custom_data 值应为:
{
"customDataBaz": {
"baz": "baz"
}
}
也就是说,更新后的字段值与之前的值无关。