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 集合,但存储在用户的身份验证访问令牌中并从中进行读取。如果用户具有有效的访问令牌,在基本文档发生变化时,只有在他们刷新访问令牌或重新身份验证后,才会更新该会话中的自定义数据。

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

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

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

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

  • 使用来自函数、Atlas Device 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 就会阻止您删除该函数。若要删除该函数,请先更改自定义用户数据配置以使用其他用户创建函数。

您可以在 App Services Admin 用户界面中配置和启用自定义用户。

1

单击左侧导航菜单中的 App Users 。然后,选择User Settings标签页并找到Custom User Data部分。

2

单击 Enable Custom User Data 开关将其设置为 On

用于在 App Services 用户界面中启用自定义用户数据的切换按钮,设置为打开。
点击放大
3

必须将应用程序用户的自定义数据存储在 MongoDB Atlas 关联集群的单个集合中。要配置应用程序从该集合读取用户数据,需要指定以下值:

  • Cluster Name:包含自定义用户数据集合的链接 MongoDB 集群的名称。

  • Database Name包含自定义用户数据集合的 MongoDB 数据库的名称。

  • Collection Name:包含自定义用户数据的 MongoDB 集合的名称。

App Services 用户界面中集合和用户 ID 字段的输入框。
点击放大
4

自定义用户数据集合中的每个文档都有一个字段将其映射到特定的应用程序用户。该字段的类型必须为 ObjectID,或表示该 ObjectID 的 string 类型。此字段必须存在于映射到用户的每个文档中。

User ID Field 输入框中指定包含每个用户 ID 的字段名称。

注意

如果两个文档包含相同用户 ID,一个存储为字符串,另一个存储为 ObjectID,则 App Services 将具有字符串类型的文档映射到用户。

5

如果要使用用户创建的 Function ,请在内联编辑器中定义它或按名称引用现有函数。

6

配置自定义用户数据集合后,您可以通过部署您的应用程序使自定义用户数据可供客户端应用程序使用。要从 App Services 用户界面部署草稿应用程序,请执行以下步骤:

  1. 单击左侧导航菜单中的 Deploy(函数)。

  2. 在部署历史记录表中找到草稿,然后单击 Review & Deploy Changes

  3. 查看更改的差异,然后单击 Deploy

一旦应用程序成功部署,App Services 就会开始将自定义数据与用户关联起来。用户登录时,App Services 会自动在自定义用户数据集合中查询有无在指定 User ID Field 中包含该用户 ID 的文档。如发现匹配的文档,App Services 会在该用户对应用户对象custom_data 字段中显示该文档中的数据。

1

要使用 App Services 定义自定义用户数据,您需要应用程序配置文件的本地副本。

要提取最新版本应用的本地副本,请运行以下命令:

appservices pull --remote="<Your App ID>"

提示

您还可以从 App Services 用户界面的Deploy > Export App屏幕下载应用程序配置文件的副本。

2

您必须将应用程序用户的自定义数据存储在关联的 Atlas 集群的单个集合中。集合中的每个文档都应包含一个特定字段,其中包含它描述的 App Services 用户的用户 ID。

要将应用程序配置为从此集合中读取用户数据,请在/auth/custom_user_data.json中定义自定义用户数据配置文档

/auth/custom_user_data.json
{
"enabled": <Boolean>,
"mongo_service_name": "<MongoDB Data Source Name>",
"database_name": "<Database Name>",
"collection_name": "<Collection Name>",
"user_id_field": "<User ID Field Name>",
"on_user_creation_function_name": "<Function Name>"
}
3

配置自定义用户数据后,您可以将更新的配置推送到远程应用程序。 App Services CLI 在推送更新时立即部署更新。

appservices push --remote="<Your App ID>"

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

当您更改用户的自定义用户数据文档时,用户的权限将自动刷新。他们的用户会话将终止,然后自动刷新。

为了使用户权限自动刷新,自定义用户数据文档应存储在普通集合中,而不是视图时间序列集合中。

要自动刷新权限,请勿删除自定义用户数据文档。相反,请取消设置文档中的所有非 ID 字段。

例子

考虑以下文档,其中为用户分配了读取和写入权限:

自定义用户数据文档
{
"_id": "63ed2erealobjectid78e526",
"user_id": "63ed2dbe5960df2af7fd216e",
"canRead": true,
"canWrite": true,
}

canReadcanWrite字段可帮助确定此文档集合的角色。例如, canRead字段用于确定apply_when表达式中以下readAllRole的资格:

自定义用户数据文档
{
"name": "readAllRole"
"apply_when": {"%%user.custom_data.canRead": true},
...
}

假设您想要删除用户的文档,因为他们已经很长时间没有活动了。首先,您需要通过取消设置非 ID 字段来正确删除员工的权限。该文档将如下所示:

正确更新的自定义用户数据文档
{
"_id": "63ed2erealobjectid78e526",
"user_id": "63ed2dbe5960df2af7fd216e"
}

取消设置非 ID 字段可让 App Services 根据角色自动刷新用户的权限。现在,您可以根据需要安全地删除该文档。

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

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

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

提供商
元数据字段
Facebook
  • name

  • first_name

  • last_name

  • picture

  • gender

  • birthday

  • min_age

  • max_age

  • email

谷歌
  • name

  • first_name

  • last_name

  • picture

  • email

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

重要

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

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

注意

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

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

1

您可以在 App Services 用户界面中配置和启用用户元数据。要进入配置页面,请执行以下步骤:

  • 单击左侧导航菜单中的 Authentication(函数)。

  • 选择 Authentication Providers 标签页。

  • 按下要配置其元数据的提供程序的 EDIT 按钮。

2

Google 或 Facebook

选中要启用的元数据字段旁边的复选框。

用于在 App Services 用户界面中启用用户元数据字段的复选框
点击放大

自定义 JWT 身份验证

您可以指定身份提供程序支持的元数据字段。按下 Add Field 按钮后,请定义:

  • 路径

  • 字段名称

  • 该字段是可选字段还是必填字段

有关更多信息,请参阅:JWT 元数据字段

在 App Services 用户界面中添加必需/可选元数据、路径和名称
点击放大

配置要访问的元数据后,按 Save Draft 按钮。

3

更新元数据配置后,必须部署应用程序。要从 App Services 用户界面部署草稿应用程序,请执行以下步骤:

  1. 单击左侧导航菜单中的 Deploy(函数)。

  2. 在部署历史记录表中找到草稿,然后单击 Review & Deploy Changes

  3. 查看更改的差异,然后单击 Deploy

一旦应用程序成功部署,App Services 就会开始将元数据与用户关联起来。当用户登录时,App Services 会请求用户权限以访问所请求的元数据。如果用户同意,App Services 就会公开该用户的用户对象中的数据。

1

要使用 AppServices 更新您的应用,您需要其配置文件的本地副本。

要提取最新版本应用的本地副本,请运行以下命令:

appservices pull --remote="<Your App ID>"

提示

还可以从 App Services 用户界面下载应用程序配置文件的副本。从应用程序仪表盘转到Deploy > Export App屏幕。

2

您可以在/auth/providers.json中找到应用程序的身份验证提供程序metadata_fields 。更新此数组以从身份验证提供程序请求用户元数据。

Google 或 Facebook

该数组类似于:

/auth/providers.json
{ ...other config details...
"metadata_fields": [
{
"required": false,
"name": "name"
},
{
"required": false,
"name": "gender"
}
]
}

自定义 JWT 身份验证

metadata_fields 数组还有一个附加属性field_name 。在自定义 JWT 身份验证中, name表示字段的路径。 field_name表示字段的名称。

/auth/providers.json
{ ...other config details...
"metadata_fields": [
{
"required": true,
"name": "user.name",
"field_name": "name"
},
{
"required": false,
"name": "user.favoriteColor",
"field_name": "favoriteColor"
}
]
}
3

配置自定义用户数据后,您可以将更新的配置推送到远程应用程序。 App Services CLI 在推送更新时立即部署更新。

appservices push --remote="<Your App ID>"
1

使用您的 MongoDB Atlas API 密钥对调用管理员用户身份验证端点:

curl -X POST \
https://services.cloud.mongodb.com/api/admin/v3.0/auth/providers/mongodb-cloud/login \
-H 'Content-Type: application/json' \
-H 'Accept: application/json' \
-d '{
"username": "<Public API Key>",
"apiKey": "<Private API Key>"
}'

如果身份验证成功,响应正文将包含一个具有access_token值的 JSON 对象:

{
"access_token": "<access_token>",
"refresh_token": "<refresh_token>",
"user_id": "<user_id>",
"device_id": "<device_id>"
}

access_token授予对 Atlas App Services Admin API 的访问权限。您必须将其作为持有者令牌包含在所有 Admin API 请求的Authorization标头中。

提示

另请参阅:

2

更新身份验证提供程序端点发送请求。在请求正文中,为提供程序定义metadata_fields

确保包括您的 Admin API access_token 、包含您的应用的 Atlas 项目的groupId 、应用的内部appId十六进制字符串以及身份验证提供程序的_id值:

curl --request PATCH 'https://services.cloud.mongodb.com/api/admin/v3.0/groups/{groupId}/apps/{appId}/auth_providers/{providerId}' \
--header 'Authorization: Bearer <access_token>' \
--header 'Content-Type: application/json' \
--data '{
"_id": "<Provider ID>",
"name": "oauth2-facebook",
"type": "oauth2-facebook",
"redirect_uris": ["https://example.com/"],
"config": {
"clientId": "<Facebook Client ID>"
},
"secret_config": {
"clientSecret": "<Facebook Client Secret Name>"
},
"metadata_fields": [
{ "required": false, "name": "name" },
{ "required": true, "name": "first_name" },
{ "required": true, "name": "last_name" },
{ "required": false, "name": "picture" },
{ "required": false, "name": "gender" },
{ "required": false, "name": "birthday" },
{ "required": false, "name": "min_age" },
{ "required": false, "name": "max_age" },
{ "required": false, "name": "email" }
],
"disabled": false
}'
curl --request PATCH 'https://services.cloud.mongodb.com/api/admin/v3.0/groups/{groupId}/apps/{appId}/auth_providers/{providerId}' \
--header 'Authorization: Bearer <access_token>' \
--header 'Content-Type: application/json' \
--data '{
"_id": "<Provider ID>",
"name": "oauth2-google",
"type": "oauth2-google",
"redirect_uris": ["https://example.com/"],
"config": {
"clientId": "<Google Client ID>"
},
"secret_config": {
"clientSecret": "<Google Client Secret Name>"
},
"metadata_fields": [
{ "required": false, "name": "name" },
{ "required": true, "name": "first_name" },
{ "required": true, "name": "last_name" },
{ "required": false, "name": "picture" },
{ "required": false, "name": "gender" },
{ "required": false, "name": "birthday" },
{ "required": false, "name": "min_age" },
{ "required": false, "name": "max_age" },
{ "required": false, "name": "email" }
],
"disabled": false
}'
curl --request PATCH 'https://services.cloud.mongodb.com/api/admin/v3.0/groups/{groupId}/apps/{appId}/auth_providers/{providerId}' \
--header 'Authorization: Bearer <access_token>' \
--header 'Content-Type: application/json' \
--data '{
"_id": "<Provider ID>",
"name": "custom-token",
"type": "custom-token",
"metadata_fields": [
{
"required": true,
"name": "jwt.field.path",
"field_name": "metadataFieldName"
}
],
"config": {
"audience": [],
"requireAnyAudience": false,
"signingAlgorithm": "HS256",
"useJWKURI": false
},
"secret_config": {
"signingKeys": [
"<JWT Signing Key>"
]
},
"disabled": true
}'

如果成功配置提供者的元数据字段,App Services 将返回204响应。

注意

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

  • 为了确保元数据是最新的,用户应在切换到其他身份验证提供者后重新进行身份验证。不这样做可能会导致过时的元数据反映在 UI 的 App Users 页面的 Users 表中,用于响应那些使用身份验证提供者的请求。

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

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

后退

创建一个用户

来年

读取用户元数据