用户数据结构
用户是身份服务中的核心实体。在 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 控制台 或 Logto Management API 查询用户资料,例如 GET /api/users/:userId
。
基础数据
下面我们来逐一介绍用户 基础数据 中的所有属性。
id
id 是在 Logto 中用于唯一标识用户的自动生成主键。
username
username 用于通过 用户名 和密码登录。
其值来源于用户首次注册时填写的用户名。它可能为 null
。非 null 值最长不超过 128 个字符,只能包含字母、数字和下划线(_
),且不能以数字开头。区分大小写。
primary_email
primary_email 是用户的邮箱地址,用于通过邮箱和密码 / 验证码登录。
其值通常来源于用户首次注册时填写的邮箱地址。它可能为 null
。最大长度为 128。
primary_phone
primary_phone 是用户的手机号,用于通过手机号和密码 / 短信验证码登录。
其值通常来源于用户首次注册时填写的手机号。它可能为 null
。非 null 值应包含以国家区号(不含加号 +
)开头的数字。
name
name 是用户的全名。最大长度为 128。
avatar
avatar 是指向用户头像图片的 URL。最大长度为 2048。
如果用户通过 Google、Facebook 等社交连接器注册,其值可能来自社交用户信息。
该属性映射到 OpenID Connect 标准中的 picture
声明 (Claim)。
profile
profile 存储了 OpenID Connect 标准声明 (Claims) 中未包含在用户属性中的其他信息。
其类型定义可在此文件中找到。以下是类型定义的副本:
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
表示所有属性都是可选的。
与其他标准声明 (Claims) 不同的是,profile
中的属性只有在值不为空时才会包含在 ID 令牌 (ID token) 或 userinfo 接口响应中,而其他标准声明 (Claims) 的值为空时会返回 null
。
application_id
application_id 的值来源于用户首次登录的应用程序。它可能为 null
。
last_sign_in_at
last_sign_in_at 是用户上次登录时的带时区时间戳。
created_at
created_at 是用户注册账号时的带时区时间戳。
updated_at
updated_at 是用户资料信息最后一次被更新时的带时区时间戳。
has_password
has_password 是一个布尔值,表示用户是否设置了密码。你可以在 控制台 > 用户管理 的详情页查看和管理此状态,包括设置新密码或重置密码。
password_encrypted
password_encrypted 用于存储用户的加密密码。
其值来源于用户首次注册时填写的密码。它可能为 null
。如果非 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 控制台管理该值。
一旦用户被停用,已授予的刷新令牌 (Refresh tokens) 会立即被吊销,用户将无法再通过 Logto 进行认证 (Authentication)。
mfa_verification_factors
mfa_verification_factors 是一个数组,列出了与用户账户关联的多因素认证 (MFA)方式。可能的值包括:Totp(认证器应用 OTP)、WebAuthn(Passkey)、BackupCode。
mfaVerificationFactors: ("Totp" | "WebAuthn" | "BackupCode")[];
社交身份
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"
}
}
}
SSO 身份
sso_identities 包含通过企业单点登录 (SSO)(即通过企业连接器单点登录](/connectors/enterprise-connectors))获取的用户信息。每个用户的 ssoIdentities 都存储在一个独立的 JSON 对象中。
从 SSO 身份提供商同步的数据取决于企业连接器中配置的 scopes。以下是 TypeScript 类型定义:
type SSOIdentity = {
issuer: string;
identityId: string;
detail: JsonObject; // 参见 https://github.com/withtyped/withtyped/blob/master/packages/server/src/types.ts#L12
};
自定义数据
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 中存放敏感数据。
自定义数据可通过自定义 JWT 令牌声明 (Claims)在用户登录后访问,而 JWT 令牌是 base64 编码(非加密)的,并且经常在网络中传输,任何敏感数据都容易被暴露。
你也可以通过 Management API 获取包含 custom_data 的用户资料,并将其发送到前端应用或外部后端服务。因此,将敏感信息放在 custom_data 中可能导致数据泄露。
如果你仍然希望将敏感信息放入 custom_data,建议先进行加密。只在可信方(如你的后端服务)进行加解密,避免在前端应用中处理。这样可以最大程度减少用户 custom_data 意外泄露时的损失。
如何收集和更新用户自定义数据
- 使用收集用户资料功能,在用户注册时收集自定义数据。
- 使用 Account API 实现终端用户资料或账户设置。
- 使用
GET /api/my-account
获取所有用户数据。 - 使用
PATCH /api/my-account
更新用户的 custom_data。
- 使用
- 使用 Management API 进行用户管理或高级自定义流程:
- 使用
GET /api/users/{userId}
获取所有用户数据。 - 使用
PATCH /api/users/{userId}/custom-data
更新用户的 custom_data。
- 使用
- 你的支持团队可以直接在 控制台 > 用户管理 中更新用户 custom_data。了解更多关于查看和更新用户资料。
请谨慎更新。更新用户的 custom_data 会完全覆盖存储中的原始内容。
例如,如果你调用更新 custom_data API 时的输入如下(假设原始 custom_data 如前面的示例数据):
{
"customDataBaz": {
"baz": "baz"
}
}
那么更新后的 custom_data 值应为:
{
"customDataBaz": {
"baz": "baz"
}
}
也就是说,更新后的字段值与之前的值无关。
属性参考
以下数据库用户表字段(除 password_encrypted 和 password_encryption_method 外)在用户资料中可见,这意味着你可以通过 Management API 查询它们。
名称 | 类型 | 描述 | 唯一 | 必填 |
---|---|---|---|---|
id | string | 唯一标识符 | ✅ | ✅ |
username | string | 用于登录的用户名 | ✅ | ❌ |
primary_email | string | 主邮箱 | ✅ | ❌ |
primary_phone | string | 主手机号 | ✅ | ❌ |
name | string | 全名 | ❌ | ❌ |
avatar | string | 指向用户头像图片的 URL | ❌ | ❌ |
profile | object | 用户资料 | ❌ | ✅ |
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 | 用户停用标记 | ❌ | ✅ |
mfa_verifications | object[] | MFA 验证因子 | ❌ | ✅ |
- 唯一:确保数据库表某属性值的唯一性。
- 必填:确保数据库表某属性值不能为
null
。