定义自定义用户元数据
在此页面上
您可以将自定义元数据与应用的每个用户相关联。例如,您可以存储用户的首选语言、出生日期或任何其他要与用户关联的信息。
您可以从两个来源中获取用户的元数据:
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 集合,但存储在用户的身份验证访问令牌中并从中进行读取。如果用户具有有效的访问令牌,在基本文档发生变化时,只有在他们刷新访问令牌或重新身份验证后,才会更新该会话中的自定义数据。
创建和管理自定义用户数据
您负责管理自定义用户数据集合中的文件。根据您的使用场景,您可以:
保护自定义用户数据
如果应用的自定义用户数据包含个人或私有用户信息,您应限制对自定义用户数据集合的访问。考虑使用以下权限模型之一来将读写访问权限限制为仅特权用户:
用户可以读取或写入自己的自定义用户数据文档。拒绝对所有其他文档的读写访问。
例子
以下集合配置具有一个角色,当且仅当文档的
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 用户界面中配置和启用自定义用户。
指定自定义用户数据集合
必须将应用程序用户的自定义数据存储在 MongoDB Atlas 关联集群的单个集合中。要配置应用程序从该集合读取用户数据,需要指定以下值:
Cluster Name:包含自定义用户数据集合的链接MongoDB 集群的名称。
Database Name包含自定义用户数据集合的 MongoDB 数据库的名称。
Collection Name:包含自定义用户数据的 MongoDB 集合的名称。
定义用户创建函数(可选)
如果要使用用户创建的 Function ,请在内联编辑器中定义它或按名称引用现有函数。
部署更新的应用程序
配置自定义用户数据集合后,您可以通过部署您的应用程序使自定义用户数据可供客户端应用程序使用。要从 App Services 用户界面部署草稿应用程序,请执行以下步骤:
单击左侧导航菜单中的 Deploy(函数)。
在部署历史记录表中找到草稿,然后单击 Review & Deploy Changes。
查看更改的差异,然后单击 Deploy。
一旦应用程序成功部署,App Services 就会开始将自定义数据与用户关联起来。用户登录时,App Services 会自动在自定义用户数据集合中查询有无在指定 User ID Field 中包含该用户 ID 的文档。如发现匹配的文档,App Services 会在该用户对应用户对象的 custom_data
字段中显示该文档中的数据。
配置自定义用户数据
您必须将应用程序用户的自定义数据存储在关联的Atlas 集群的单个集合中。 集合中的每个文档都应包含一个特定字段,其中包含它描述的App Services用户的用户ID 。
要将应用程序配置为从此集合中读取用户数据,请在/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>" }
从客户端应用程序中访问自定义用户数据
有关演示如何从客户端应用程序访问权限和更新自定义用户数据的代码示例,请参阅Atlas Device SDK 的文档:
修改自定义用户数据中权限的最佳实践
当您更改用户的自定义用户数据文档时,用户的权限将自动刷新。 他们的用户会话将终止,然后自动刷新。
为了使用户权限自动刷新,自定义用户数据文档应存储在普通集合中,而不是存储在视图或时间序列集合中。
要自动刷新权限,请勿删除自定义用户数据文档。 相反,请取消设置文档中的所有非ID字段。
例子
考虑以下文档,其中为用户分配了读取和写入权限:
{ "_id": "63ed2erealobjectid78e526", "user_id": "63ed2dbe5960df2af7fd216e", "canRead": true, "canWrite": true, }
canRead
和canWrite
字段可帮助确定此文档集合的角色。 示例, 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 |
|
Google |
|
自定义 JWT | JWT 中由自定义 JWT 提供程序的元数据字段配置指定的任何字段。 |
重要
避免过时的身份验证提供者元数据
如果在颁发访问权限令牌后更新用户的元数据,则使用先前创建的访问权限令牌的请求将不会包含新更新的元数据。 用户元数据将在刷新访问权限令牌或重新身份验证时更新。
注意
安全和身份验证提供者元数据
身份验证提供者元数据可以由客户端和外部身份验证提供者从外部定义,应谨慎对待。您不应仅仅依赖身份验证提供者元数据来做出与安全相关的决策,例如在数据访问权限的规则表达式中使用此元数据。
配置身份验证提供程序元数据
配置用户元数据
Google 或 Facebook
选中要启用的元数据字段旁边的复选框。
自定义 JWT 身份验证
您可以指定身份提供程序支持的元数据字段。按下 Add Field 按钮后,请定义:
路径
字段名称
该字段是可选字段还是必填字段
有关更多信息,请参阅:JWT 元数据字段。
配置要访问的元数据后,按 Save Draft 按钮。
部署更新的应用程序
更新元数据配置后,必须部署应用程序。要从 App Services 用户界面部署草稿应用程序,请执行以下步骤:
单击左侧导航菜单中的 Deploy(函数)。
在部署历史记录表中找到草稿,然后单击 Review & Deploy Changes。
查看更改的差异,然后单击 Deploy。
一旦应用程序成功部署,App Services 就会开始将元数据与用户关联起来。当用户登录时,App Services 会请求用户权限以访问所请求的元数据。如果用户同意,App Services 就会公开该用户的用户对象中的数据。
配置元数据字段
您可以在/auth/providers.json
中找到应用的身份验证提供者metadata_fields 。 更新此大量以从身份验证提供者请求用户元数据。
Google 或 Facebook
该大量类似于:
{ ...other config details... "metadata_fields": [ { "required": false, "name": "name" }, { "required": false, "name": "gender" } ] }
自定义 JWT 身份验证
metadata_fields大量还有一个附加属性field_name
。 在自定义JSON web token身份验证中,name
表示字段的路径。 field_name
表示字段的名称。
{ ...other config details... "metadata_fields": [ { "required": true, "name": "user.name", "field_name": "name" }, { "required": false, "name": "user.favoriteColor", "field_name": "favoriteColor" } ] }
对 MongoDB Atlas 用户进行身份验证
使用您的 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
授予对App Services Admin API的访问权限。 您必须将其作为持有者令牌包含在所有 Admin API请求的Authorization
标头中。
配置元数据字段
向更新身份验证提供者端点发送请求。 在请求正文中,为提供商定义metadata_fields
。
确保包含您的 Admin API access_token
、包含您的应用的Atlas项目的 groupId
、应用的内部 appId
十六进制string以及身份验证提供者的 _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 的文档: