Docs 菜单

Docs 主页Atlas App Services

定义自定义用户元数据

在此页面上

  • 概述
  • 自定义用户数据
  • 创建和管理自定义用户数据
  • 保护自定义用户数据
  • 用户创建函数
  • 启用自定义用户数据
  • 从客户端应用程序中访问自定义用户数据
  • 身份验证提供程序元数据
  • 配置身份验证提供程序元数据
  • 从客户端应用程序访问用户元数据

您可以将自定义元数据与应用的每个用户相关联。例如,您可以存储用户的首选语言、出生日期或任何其他要与用户关联的信息。

您可以从两个来源中获取用户的元数据:

  • MongoDB Atlas 中存储自定义用户数据的集合。您可以通过用户 ID 将每个用户与集合中的文档相关联。您可以在每个文档中存储任意数据。

  • 身份验证提供程序。如果提供程序使用 JSON Web 令牌,例如 Google、Facebook 或自定义提供程序,则可以在提供程序配置中定义元数据字段,将来自用户 JWT 的数据与其用户帐户关联。

您可以将有关应用程序用户的任意数据存储在 MongoDB 集合中。应用通过查询用户 ID 的特定字段,将每个用户映射到集合中的文档。当用户进行身份验证时,应用会查找用户的数据并将其包含在访问令牌中。

请考虑一个 ID 为 "63ed2dbe5960df2af7fd216e" 的用户。如果设置自定义用户数据集合以将该用户的 ID 存储在 userId 字段中,该用户将映射到以下文档:

{
"_id": "63ed2e4fb7f367c92578e526",
"user_id": "63ed2dbe5960df2af7fd216e",
"preferences": {
"preferDarkMode": true
},
"dateOfBirth": "1989-03-11T00:00:00.000Z"
}

在使用自定义用户数据时,请记住以下事项:

  • 为每个用户存储一个文档:包含用户数据的文档必须在特定字段中包含用户的 ID。如果多个文档指定同一用户的 ID,App Services 仅公开第一个插入的文档中的数据。

  • 尽量减少自定义用户数据大小:用户的完整自定义用户文档包含在其访问令牌中。一般来说,应尽量减少自定义用户数据文档大小(例如小于 16KB)。其他服务可能会限制 HTTP 头部大小,这意味着较大的自定义用户数据对象可能会导致集成问题。

  • 自定义数据可能过时:用户的自定义数据源自 MongoDB 集合,但存储在用户的身份验证访问令牌中并从中进行读取。如果用户具有有效的访问令牌,在基本文档发生变化时,只有在他们刷新访问令牌或重新身份验证后,才会更新该会话中的自定义数据。

您负责管理自定义用户数据集合中的文件。根据您的使用场景,您可以:

  • 当每个用户使用用户创建功能注册您的应用程序时,自动为他们创建一个文档。此函数在向用户颁发访问令牌之前运行,因此您添加的数据将在用户首次登录时位于访问令牌中。

  • 使用身份验证触发器,在用户注册或登录时更新其自定义数据,并在其帐户被删除时删除其数据。触发器以异步方式运行,并可能在创建用户的访问令牌后完成。

  • 使用定时触发器定期更新或删除自定义用户数据。

  • 通过函数、Realm SDK、MongoDB 驱动程序或 MongoDB Compass 使用标准 CRUD 操作手动创建、更新和删除集合中的文档。

如果应用的自定义用户数据包含个人或私有用户信息,您应限制对自定义用户数据集合的访问。考虑使用以下权限模型之一来将读写访问权限限制为仅特权用户:

  • 用户可以读取或写入自己的自定义用户数据文档。拒绝对所有其他文档的读写访问。

    例子

    以下集合配置具有一个角色,当且仅当文档的 user_id 字段中包含用户的 ID 时,该角色才会为用户授予文档的读写访问权限。

    自定义用户数据集合配置
    {
    "database": "<Database Name>",
    "collection": "<Collection Name>",
    "roles": [
    {
    "name": "ThisUser",
    "apply_when": { "user_id": "%%user.id%%" },
    "insert": false,
    "read": true,
    "write": true,
    "search": false,
    "delete": false
    }
    ],
    "filters": []
    }
  • 任何用户都不得读取或写入任何自定义用户数据文档。相反,应使用系统函数来代表用户管理自定义用户数据。

您可以定义一个函数,它在每次新用户成功注册但尚未创建新用户帐户时运行。如果该函数抛出错误或出现其他问题,则用户帐户创建失败。这样就能确保用户在创建后总是有自定义数据与之关联。

该函数接收用户元数据对象作为其唯一参数。您可以使用它为用户创建新的自定义用户数据文档。

exports = async function onUserCreation(user) {
const customUserDataCollection = context.services
.get("mongodb-atlas")
.db("myapp")
.collection("users");
try {
await customUserDataCollection.insertOne({
// Save the user's account ID to your configured user_id_field
user_account_id: user.id,
// Store any other user data you want
favorite_color: "blue",
});
} catch (e) {
console.error(`Failed to create custom user data document for user:${user.id}`);
throw e
}
}

提示

一旦配置好用户创建函数,App Services 就会阻止您删除该函数。若要删除该函数,请先更改自定义用户数据配置以使用其他用户创建函数。

有关演示如何从客户端应用程序访问和更新自定义用户数据的代码示例,请参阅 Realm SDK 的文档:

Atlas App Services 可以从身份验证提供程序中读取用户元数据。然后,App Services 在每个用户的用户对象字段中公开他们的数据。例如,您可能希望访问用户的姓名、电子邮件、生日或性别。

您可以配置 App Services,使其在用户登录时请求带有访问令牌的元数据。您可以使用客户端 SDK 从已登录用户的对象访问该数据。

您可以在配置身份验证提供程序时定义要请求的元数据。指定要通过用户账户访问的可选元数据字段。这些元数据字段因提供程序而异。

提供商
元数据字段
Facebook
  • name

  • first_name

  • last_name

  • picture

  • gender

  • birthday

  • min_age

  • max_age

  • email

Google
  • name

  • first_name

  • last_name

  • picture

  • email

自定义 JWT
JWT 中由自定义 JWT 提供程序的元数据字段配置指定的任何字段。

重要

避免过时的身份验证提供者元数据

如果在颁发访问令牌后更新用户的元数据,则使用先前创建的访问令牌的请求将不会包含新更新的元数据。用户元数据将在刷新访问令牌或重新身份验证时更新。

注意

安全和身份验证提供者元数据

身份验证提供程序元数据可以由客户端和外部身份验证提供程序从外部定义,应谨慎对待。您不应仅依赖身份验证提供程序元数据来做出与安全相关的决策,例如在规则表达式中使用此元数据来确定数据访问权限。

注意

给使用多个关联身份验证提供程序的用户的提示

  • 为确保元数据是最新的,用户应在切换到不同的身份验证提供者后重新进行身份验证。否则,可能会导致用户界面的App Users页面的 Users表以及使用身份验证提供程序的请求反映过时的元数据。

  • 如果用户在身份验证提供程序之间切换,则元数据传播可能最多需要30分钟。始终保证请求具有与所使用的身份验证提供程序关联的最新元数据。

有关演示如何从客户端应用程序访问用户元数据的代码示例,请参阅 Realm SDK 的文档:

← 创建应用用户