我正在尝试在Meteor.js应用程序和Mongo服务器之间设置无密码身份验证.
为此,我需要将pem和crt文件呈现给连接.MONGO_URL连接字符串仅接受有关如何执行身份验证的参数,但不引用具有证书的文件.我假设,我需要将cert文件作为参数传递给连接.类似于这里描述的.
如何在Meteor.js中做到这一点?
基本上我想实现相当于:
mongo mongo.example.com/example -ssl -sslPEMKeyFile client.pem --sslCAFile server.crt
然后描述这里
db.getSiblingDB("$external").auth( { mechanism: "MONGODB-X509", user: "CN=myName,OU=myOrgUnit,O=myOrg,L=myLocality,ST=myState,C=myCountry" } )
这在使用mogo客户端时工作正常,但在Meteor中我到目前为止只是达到理解的程度,我很可能需要使用下面的连接字符串(或类似的东西)
MONGO_URL=mongodb://mongo.example.com:27017/example?ssl=true&authSource=$external&authMechanism=MONGODB-X509
但问题仍然存在 - 如何将证书传递给连接?
更新:有使用本机noddejs mongo驱动程序处理问题的答案.问题是 - 如何将此移植到Meteor.
更新2015-12-31:我已经接受了在定义Collection时指向使用不同连接对象的答案.分别为每个系列做这件事很麻烦,但它似乎是现在唯一可行的方法.此外,如果需要,可能会创建一些MySslCollection,其他人可以使用它来继承连接详细信息.这尚未经过测试.
正如另一个答案所指出的那样,这里的选项从版本1.4开始已经改变,你现在可以打电话了
Mongo.setConnectionOptions({ ... });
请参阅文档以获取更多详细信息.
这是一个有趣的兔子洞...我想我找到了一个解决方案/解决方案来解决你的问题(可能还有其他问题).
我的解决方法的快速描述是在创建集合时指定mongodb服务器选项.这必须在服务器代码上完成,以避免分发您的ssl密钥/证书.像这样:
new Mongo.Collection("collection_name", { connection: DDP.connect("mongodb://mongo.example.com:27017/example?ssl=true&authSource=$external&authMechanism=MONGODB-X509", { server: { sslCert:[CERT_CONTENTS], sslKey:[KEY_CONTENTS], sslValidate:false } }) });
Hacky方法
既然你问过是否有办法这样做而没有为每个创建的集合添加选项,我决定再看看.我没有测试过这些方法,但它们看起来很合理,如果非常黑客的话.
1)在重新连接方法中使用未记录的选项参数passthru设置一个在连接状态下运行的函数.https://github.com/meteor/meteor/blob/master/packages/ddp-client/livedata_connection.js#L996
Tracker.autorun(function () { var status = Meteor.status(); if(status == 'failed') Meteor.reconnect({ server: { sslCert:[CERT_CONTENTS], sslKey:[KEY_CONTENTS], sslValidate:false } }); });
2)猴子修补默认的连接代码(这我不太确定工作,因为我没有花时间去理解这个实际上mongo内部代码实际设置的时间).https://github.com/meteor/meteor/blob/dc3cd6eb92f2bdd1bb44000cdd6abd1e5d0285b1/packages/mongo/remote_collection_driver.js
MongoInternals.defaultRemoteCollectionDriver = _.once(function () { var connectionOptions = { server: { sslCert:[CERT_CONTENTS], sslKey:[KEY_CONTENTS], sslValidate:false } }; var mongoUrl = process.env.MONGO_URL; if (process.env.MONGO_OPLOG_URL) { connectionOptions.oplogUrl = process.env.MONGO_OPLOG_URL; } if (! mongoUrl) throw new Error("MONGO_URL must be set in environment"); return new MongoInternals.RemoteCollectionDriver(mongoUrl, connectionOptions); });
这些答案的旅程:
从您链接的答案开始,我发现Meteor创建其MongoDB连接的位置:https://github.com/meteor/meteor/blob/dc3cd6eb92f2bdd1bb44000cdd6abd1e5d0285b1/packages/mongo/mongo_driver.js#L173
然后我找到了被调用的地方:https://github.com/meteor/meteor/blob/3d2282d9ad0b570b913a70d215cd968019d912df/packages/mongo/remote_collection_driver.js#L4
追踪被调用的地方让我看到了Collections实例化连接这一事实:https://github.com/meteor/meteor/blob/15cdbca24888bfdff3ad43c1891a1719c09b3dc5/packages/mongo/collection.js#L102
我可以从那里看到一些选项可以覆盖使用没有指定选项的默认Mongo连接.查看集合的Meteor文档http://docs.meteor.com/#/full/mongo_collection显示:
选项
连接对象
将管理此集合的服务器连接.如果未指定,则使用默认连接.传递调用DDP.connect的返回值以指定其他服务器.传递null以指定无连接.Unmanaged(name为null)集合无法指定连接.
所以看看DDP.connect http://docs.meteor.com/#/full/ddp_connect的文档,我们达到了一个死胡同,因为它只需要一个网址...但是等待...在github上搜索代码之后我可以看到DDP.connect确实采用了一个选项参数:https://github.com/meteor/meteor/blob/master/packages/ddp-client/livedata_connection.js#L1641
这样就完成了我们的任务.