Docs 菜单
Docs 主页
/ /
Atlas App Services
/

传输协议

在此页面上

  • Overview
  • 兼容的客户端
  • 连接字符串(Connection Strings)
  • 凭证
  • 区域
  • 参数
  • 启用传输协议连接
  • 通过传输协议进行连接
  • 使用连接 连接到Atlas App Servicesstring
  • 读取和修改数据
  • 调用函数
  • 调用服务操作 [已弃用]
  • 获取登录用户的数据

Atlas App Services原生实现了MongoDB传输协议的一个子集,它允许您使用标准MongoDB驱动程序和工具通过其链接的MongoDB Atlas数据源之一连接到应用程序。 客户端使用专门的 App Services连接string来连接和发送请求。 App Services通过传输协议支持大多数客户端功能,包括基于角色的数据访问规则函数服务操作。

对于当前没有Realm 软件开发工具包(Realm SDK)的语言来说,这是一个不错的选择。 此处的示例适用于Python 、 C++ 11 和mongo shell 。 任何支持MongoDB appName连接string 参数的 驾驶员 都可以使用传输协议连接到App Services。

注意

您可以使用以下工具和驱动程序通过连接字符串与 App Services 进行通信:

  • 4.0+ 版本的mongo shell 。

  • 任何支持MongoDB appName连接string 参数的 驾驶员。所有官方MongoDB驱动程序在其当前版本中都支持此参数。

注意

通过传输协议与App Services建立的连接可以访问权限MongoDB Service的全部功能。 但是, App Services并不支持标准工具和客户端提供的所有操作和功能。 有关详细信息,请参阅MongoDB服务限制。

要通过传输协议连接到App Services ,必须构造凭证MongoDB stringappName,其中包括应用程序 用户 的档案和特定于应用程序的 查询参数。

重要

URL 编码

您必须 对 进行URL 编码 连接字符串,然后才能使用它们连接到Atlas App Services 。默认情况下, Atlas App Services用户界面中的连接字符串已正确编码。

App Services连接字符串采用以下形式:

mongodb://<credentials>@<region>.services.cloud.mongodb.com:27020/?<parameters>

通过传输协议发出的所有操作都在您通过连接字符串指定的特定应用程序用户的上下文中运行。用户必须通过以下身份验证提供程序之一注册:

连接字符串凭证的内容取决于用户注册的身份验证提供程序:

format
<email>:<password>
字段
<email>
用户的注册电子邮件解决。
<password>
用户的密码。
例子
joe.mango@company.com:SuperSecretPassword123
format
_:<apiKey>
字段
<apiKey>
活动的应用程序API密钥。
例子
_:tOSJwYhLLam1qTAwP8rZ5M9BiHfn69w5xrya52dYeOv1PdTlD68i8gKOaN0Wy24z
format
_:<customAuthToken>
字段
<customAuthToken>
自定义身份验证JSON web token 。
例子
_:eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.
eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.
SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c

连接string必须指定托管应用的部署地区和云提供商。

全球应用使用global地区:

mongodb://<credentials>@global.services.cloud.mongodb.com:27020/?<parameters>

本地应用程序使用<region>.<cloud>格式指定云提供商和地区名称。 示例,部署到 aws-us-east-1 的应用将使用以下连接string :

mongodb://<credentials>@us-east-1.aws.services.cloud.mongodb.com:27020/?<parameters>

Atlas App Services需要特定的连接string选项,用于标识要连接的应用程序以及与您提供的档案关联的身份验证提供者。

App Services连接字符串具有以下查询参数:

Parameter
说明
authMechanism
此参数应始终设置为PLAIN
authSource
此参数应始终设置为$external
appName

希望连接的应用程序、MongoDB 服务和身份验证提供程序的唯一标识。

appName参数采用以下形式:

<app id>:<service>:<provider>
<app id>
应用的 App ID
<service>
要连接的 MongoDB 服务的名称。 此值将始终为mongodb-atlas
<provider>

您为其提供档案的身份验证提供者

Valid values:

  • local-userpass

  • api-key

  • custom-token

必须先为关联集群启用传输协议连接,然后才能使用连接字符串连接到 App Services App。

1

在左侧导航菜单的Manage部分,单击Linked Data Sources

在数据源列表中,选择要启用传输协议连接的集群。

2

MongoDB Connection String的开关设置为Enabled 。 在出现的 Authentication Method(身份验证方法)部分中,选择并配置您希望如何对传输协议连接进行身份验证。

在用户界面中启用传输协议切换
3
1

要使用App Services CLI启用MongoDB传输协议连接,您需要应用程序配置文件的本地副本。

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

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

提示

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

2

要为关联集群启用传输协议连接,请打开集群的config.json文件并将config.wireProtocolEnabled的值设立为true

{
"name": "mongodb-atlas",
"type": "mongodb-atlas",
"config": {
"wireProtocolEnabled": true,
...
}
}
3

config.json中为集群启用传输协议连接后,您可以将配置推送到远程应用。 App Services CLI在推送更新时立即部署更新。

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

Atlas App Services要通过传输协议连接到 ,请传递 URL 编码的 创建客户端时的Atlas App Services 连接string ,就像使用常规 连接string 一样。

$ mongo "mongodb://<user>:<password>@services.cloud.mongodb.com:27020/?authMechanism=PLAIN&authSource=%24external&ssl=true&appName=realm-application-abcde:mongodb-atlas:local-userpass"
mongocxx::instance instance{};
mongocxx::uri uri("mongodb://<user>:<password>@services.cloud.mongodb.com:27020/?authMechanism=PLAIN&authSource=%24external&ssl=true&appName=realm-application-abcde:mongodb-atlas:local-userpass");
mongocxx::client client(uri);
client = pymongo.MongoClient("mongodb://<user>:<password>@services.cloud.mongodb.com:27020/?authMechanism=PLAIN&authSource=%24external&ssl=true&appName=realm-application-abcde:mongodb-atlas:local-userpass")

通过传输协议连接到Atlas App Services时,您可以使用标准MongoDB CRUD操作。 Atlas App Services将基于角色的数据访问规则应用于连接string档案中指定的经过身份验证的用户上下文中的所有查询

> use HR
> db.employees.findOne();
{
"_id": ObjectId("5ae782e48f25b9dc5c51c4a5"),
"employeeId": 854271626,
"name": {
"first": "Lucas",
"last": "Lewis"
},
"role": "PM",
"salary": 200000,
"email": "Lucas.Lewis.0271@company.com",
"password": "<password>",
"manager": {
"id": 328892725,
"email": "Daniel.Wilson.0474@company.com",
"name": {
"first": "Daniel",
"last": "Wilson"
}
}
}
mongocxx::database db = client["HR"];
mongocxx::collection employees = db["employees"];
bsoncxx::stdx::optional<bsoncxx::document::value> result =
collection.find_one({});
if(result) {
std::cout << bsoncxx::to_json(result) << "\n";
}
>>> db = client["HR"]
>>> employee = db["employees"].find_one();
>>> pprint(employee)
{'_id': ObjectId('5ae782e48f25b9dc5c51c4a5'),
'email': 'Lucas.Lewis.0271@company.com',
'employeeId': 854271626.0,
'manager': {'email': 'Daniel.Wilson.0474@company.com',
'id': 328892725.0,
'name': {'first': 'Daniel', 'last': 'Wilson'}},
'name': {'first': 'Lucas', 'last': 'Lewis'},
'password': '<password>',
'role': 'PM',
'salary': 200000}

您可以使用callFunction数据库命令调用函数。

命令
说明
原型
callFunction
调用指定函数并返回任何结果。
{
callFunction: <function name>,
arguments: [<arg1>, <arg2>, ...]
}
> db.runCommand({
... callFunction: "getEmployeeById",
... arguments: ["5ae782e48f25b9dc5c51c4a5"]
...});
{
"ok" : 1,
"response" : {
"_id": ObjectId("5ae782e48f25b9dc5c51c4a5"),
"employeeId": 854271626,
"name": {
"first": "Lucas",
"last": "Lewis"
},
"role": "PM",
"salary": 200000,
"email": "Lucas.Lewis.0271@company.com",
"password": "<password>",
"manager": {
"id": 328892725,
"email": "Daniel.Wilson.0474@company.com",
"name": {
"first": "Daniel",
"last": "Wilson"
}
}
}
}
db.runCommand({
callFunction: "getEmployeeById",
arguments: ["5ae782e48f25b9dc5c51c4a5"]
});
>>> function_result = db.command("callFunction", "getEmployeeById",
... arguments=["5ae782e48f25b9dc5c51c4a5"]
...)
>>> pprint.pprint(function_result)
{'ok': 1,
'response': {'_id': ObjectId('5ae782e48f25b9dc5c51c4a5'),
'email': 'Lucas.Lewis.0271@company.com',
'employeeId': 854271626.0,
'manager': {'email': 'Daniel.Wilson.0474@company.com',
'id': 328892725.0,
'name': {'first': 'Daniel', 'last': 'Wilson'}},
'name': {'first': 'Lucas', 'last': 'Lewis'},
'password': '<password>',
'role': 'PM',
'salary': 200000}}

您可以使用callServiceFunction数据库命令调用服务操作。

命令
说明
原型
callServiceFunction
调用指定的服务动作并返回任何结果。
{
callServiceFunction: <function name>,
service: <service name>,
arguments: [<arg1>, <arg2>, ...]
}
> db.runCommand({
... callServiceFunction: "get",
... service: "http",
... arguments: [{ url: "https://jsonplaceholder.typicode.com/todos/1" }]
... });
{
"ok" : 1,
"response" : {
"status" : "200 OK",
"statusCode" : 200,
"contentLength" : NumberLong(-1),
"headers" : {
"Content-Type" : ["application/json; charset=utf-8"],
"Connection" : ["keep-alive"],
"Vary" : ["Origin, Accept-Encoding"],
"X-Content-Type-Options" : ["nosniff"],
"Via" : ["1.1 vegur"],
"X-Powered-By" : ["Express"],
"Cf-Cache-Status" : ["HIT"],
"Expect-Ct" : ["max-age=604800, report-uri=\"https://example.com/cdn-cgi/beacon/expect-ct\""],
"Set-Cookie" : ["__cfduid=d7f650e765d41beb7598ce2ab62d0c0191536867096; expires=Fri, 13-Sep-19 19:31:36 GMT; path=/; domain=.typicode.com; HttpOnly"],
"Access-Control-Allow-Credentials" : ["true"],
"Cache-Control" : ["public, max-age=14400"],
"Pragma" : ["no-cache"],
"Etag" : ["W/\"53-hfEnumeNh6YirfjyjaujcOPPT+s\""],
"Server" : ["example.com"],
"Cf-Ray" : ["459d08f88e1e56db-IAD"],
"Date" : ["Thu, 13 Sep 2018 19:31:36 GMT"],
"Expires" : ["Thu, 13 Sep 2018 23:31:36 GMT"]
},
"cookies" : {
"__cfduid" : {
"value" : "d7f650e765d41beb7598ce2ab62d0c0191536867096",
"path" : "/",
"domain" : ".typicode.com",
"expires" : "Mon, 01 Jan 0001 00:00:00 GMT",
"maxAge" : 0,
"secure" : false,
"httpOnly" : true
}
},
"body" : BinData(0,"ewogICJ1c2VySWQiOiAxLAogICJpZCI6IDEsCiAgInRpdGxlIjogImRlbGVjdHVzIGF1dCBhdXRlbSIsCiAgImNvbXBsZXRlZCI6IGZhbHNlCn0=")
}
}
db.runCommand({
callServiceFunction: "get",
service: "http",
arguments: [{ url: "https://jsonplaceholder.typicode.com/todos/1" }]
});
>>> result = db.command("callServiceFunction", "get",
... service="http",
... arguments=[{"url": "https://jsonplaceholder.typicode.com/todos/1"}]
...)
>>> pprint.pprint(result)
{'ok': 1,
'response': {'body': b'{\n "userId": 1,\n "id": 1,\n "title": "delectus aut'
b' autem",\n "completed": false\n}',
'contentLength': -1,
'cookies': {'__cfduid': {'domain': '.typicode.com',
'expires': 'Mon, 01 Jan 0001 00:00:00 '
'GMT',
'httpOnly': True,
'maxAge': 0,
'path': '/',
'secure': False,
'value': 'd4b10004e96ca7fee0be03dceebaf2ab71536866400'}},
'headers': {'Access-Control-Allow-Credentials': ['true'],
'Cache-Control': ['public, max-age=14400'],
'Cf-Cache-Status': ['HIT'],
'Cf-Ray': ['459cf7fc7e20c1bd-IAD'],
'Connection': ['keep-alive'],
'Content-Type': ['application/json; charset=utf-8'],
'Date': ['Thu, 13 Sep 2018 19:20:00 GMT'],
'Etag': ['W/"53-hfEnumeNh6YirfjyjaujcOPPT+s"'],
'Expect-Ct': ['max-age=604800, '
'report-uri="https://example.com/cdn-cgi/beacon/expect-ct"'],
'Expires': ['Thu, 13 Sep 2018 23:20:00 GMT'],
'Pragma': ['no-cache'],
'Server': ['example.com'],
'Set-Cookie': ['__cfduid=d4b10004e96ca7fee0be03dceebaf2ab71536866400; '
'expires=Fri, 13-Sep-19 19:20:00 GMT; '
'path=/; domain=.typicode.com; '
'HttpOnly'],
'Vary': ['Origin, Accept-Encoding'],
'Via': ['1.1 vegur'],
'X-Content-Type-Options': ['nosniff'],
'X-Powered-By': ['Express']},
'status': '200 OK',
'statusCode': 200}}

您可以使用userProfile数据库命令获取经过身份验证的用户的用户对象

命令
说明
原型
userProfile
返回经过身份验证的用户的用户对象
{
userProfile: 1
}
> db.runCommand({ userProfile: 1 });
{
"ok" : 1,
"profile" : {
"userid" : "5ad7a79e8f25b975898d77b8",
"domainid" : ObjectId("5ad7a69746224c054067c8b1"),
"identities" : [
{
}
],
"data" : "{\"email\":\"joe.mango@company.com\"}",
"type" : "normal",
"roleassignments" : [ ]
}
}
db.runCommand({ userProfile: 1 });
>>> result = db.command("userProfile", 1)
>>> pprint.pprint(result)
{'ok': 1,
'profile': {'data': '{"email":"joe.mango@company.com"}',
'domainid': ObjectId('5ad7a69746224c054067c8b1'),
'identities': [{}],
'roleassignments': [],
'type': 'normal',
'userid': '5ad7a79e8f25b975898d77b8'}}

后退

读取偏好