跳到主要内容

用户数据结构

用户是身份服务中的核心实体。在 Logto 中,用户包含基于 OpenID Connect 协议的基础认证 (Authentication) 数据,以及自定义数据。

用户资料

每个用户都有一个包含所有用户信息的资料。

它由以下类型的数据组成:

  • 基础数据:来自用户资料的基本信息。它存储除社交 identitiescustom_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_encryptedpassword_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 意外泄露时的损失。

如何收集和更新用户自定义数据

请谨慎更新。更新用户的 custom_data 会完全覆盖存储中的原始内容。

例如,如果你调用更新 custom_data API 时的输入如下(假设原始 custom_data 如前面的示例数据):

{
"customDataBaz": {
"baz": "baz"
}
}

那么更新后的 custom_data 值应为:

{
"customDataBaz": {
"baz": "baz"
}
}

也就是说,更新后的字段值与之前的值无关。

属性参考

以下数据库用户表字段(除 password_encryptedpassword_encryption_method 外)在用户资料中可见,这意味着你可以通过 Management API 查询它们。

名称类型描述唯一必填
idstring唯一标识符
usernamestring用于登录的用户名
primary_emailstring主邮箱
primary_phonestring主手机号
namestring全名
avatarstring指向用户头像图片的 URL
profileobject用户资料
identitiesobject通过社交登录获取的用户信息
custom_dataobject可自定义属性中的附加信息
application_idstring用户首次注册的应用 ID
last_sign_in_atdate time用户上次登录时的时间戳
password_encryptedstring加密密码
password_encryption_methodstring密码加密方式
is_suspendedbool用户停用标记
mfa_verificationsobject[]MFA 验证因子
  • 唯一:确保数据库表某属性值的唯一性
  • 必填:确保数据库表某属性值不能为 null
用户数据流动的安全枢纽