【问题标题】:Use separate server for centralized users database为集中的用户数据库使用单独的服务器
【发布时间】:2020-07-16 13:29:27
【问题描述】:

我正在使用 Meteor 1.10 + mongodb。

我有多个移动聊天和信息应用程序。

这些移动应用程序是使用 Meteor DDP 库本地开发的。

但我的所有应用都有相同的用户群。

现在我想在单独的服务器上创建一个单独的流星实例,以保持用户群集中。

我需要有关如何使用流星实现此架构的建议。

牢记反应性和性能。

【问题讨论】:

标签: javascript node.js mongodb sockets meteor


【解决方案1】:

对于具有完整反应功能的集中式用户群,您需要一个授权服务器,您的应用程序(= 资源服务器)将使用该授权服务器以允许经过身份验证/授权的请求。这基本上是 OAuth2 3 层工作流。

见:

https://www.rfc-editor.org/rfc/rfc6749

https://www.oauth.com/

登录服务

您还必须编写自己的登录处理程序 (Meteor.loginWithMyCustomAuthServer) 以避免出现DDP.connect,因为这样您就必须管理两个用户群(一个用于应用程序本身,一个用于授权服务器),这将变得非常混乱。

然后,此登录处理程序在 Oauth2 授权请求成功后检索用户帐户数据,这将使授权服务器的用户群成为您注册的任何应用程序的单一事实点(阅读 Oauth2 工作流程,了解 @987654329 @ 和 secret)。

订阅用户

身份验证服务器是您在那里创建、更新或删除用户的单一事实点,成功登录后,您的本地应用将始终获取最新用户从此帐户身份验证服务器同步的数据(这也是 Meteor 使用 loginWith<Service> 的方式)

然后,您无需任何 ddp 远程连接即可为您的用户订阅应用程序本身。当然,这只有在您想要获取的用户数据实际上是针对在线用户时才有效。

如果您想订阅任何用户(数据可能尚未同步),您仍然需要远程订阅授权服务器上的发布。

请注意,为了通过此远程订阅对用户进行身份验证,您需要经过身份验证的 DDP 请求(也由以下软件包支持)。

实施

警告 - 以下是我自己的实现。这是因为我遇到了同样的问题,但在我之前没有找到其他实现。

有一个完整的帐户服务器(但一直在进行中)

https://github.com/leaonline/leaonline-accounts

它使用一个Oauth2 nodejs implementation,它被包裹在一个 Meteor 包中:

https://github.com/leaonline/oauth2-server

并且相应的登录处理程序也已创建:

https://github.com/leaonline/meteor-accounts-lea

【讨论】:

  • 嗯,让我很困惑的是移动应用端的实现是什么,我的意思是我必须使用 2 个不同端口的 2 个 DDP 连接吗?例如,我在集中式服务器上拥有所有用户,而在另一台服务器上拥有群聊,那么在这种情况下,我将如何在移动应用上响应式订阅用户和群聊?
  • 我首先不明白的是如何“订阅 10 个最新注册用户而无需任何 DDP 远程连接”。假设用户群聊在 SERVER A,用户在 SERVER B(集中式服务器)。
  • 如果您使用上述工作流程,那么就像您在任何 Meteor 应用程序中为您的 10 个最新注册用户订阅一样。这当然需要这些用户已经登录,以便他们的数据从 Auth 服务器同步到您的应用
  • 好的,但是如果他们没有登录怎么办?他们刚刚注册并注销,我仍然需要将这些用户显示在列表中。同时,如果有新用户注册,我需要该用户反应性地出现在列表顶部
  • 他们只需登录一次即可同步用户帐户
【解决方案2】:

所以我终于找到了解决办法。这可能不是处理这个问题的完美方法,但据我所知,它对我非常有效。但是是的,我仍然愿意接受建议。

目前我有 4 个连接应用程序,它们依赖于相同的用户群。

所以我决定构建 SSO(用于管理用户数据库的集中式服务器)

所有 4 个连接应用程序 ping SSO 以进行用户身份验证并获取用户相关数据。

现在这 4 个连接应用程序是使用 Meteor 开发的。

这里的主要挑战是使事物反应/实时。 例如聊天/消息、群组创建、显示用户列表和新注册用户的听众。

所以在这种情况下,用户数据库位于其他远程服务器 (SSO) 上,所以在连接应用程序时我不能:

Meteor.publish("getUsers")

所以在连接应用程序时,我决定创建一个名为的临时集合:

UserReactiveCollection

结构如下:

UserReactiveCollection.{
    _id: 1,
    userId: '2',
    createdAt: new Date()
}

我发布了订阅:

Meteor.publish("subscribeNewUserSso", function () {

    return UserReactiveCollection.find({});
});

所以为了更新UserReactiveCollection,我分别在每个连接的应用程序上公开了Rest Api。 这些 api 从 SSO 接收数据并在 UserReactiveCollection 中更新。

因此,在注册新用户时,在 SSO 方面。我 ping 这些 API(在连接应用程序时)并在有效负载中发送插入的 userId。

所以现在那些正在连接的应用程序从订阅接收onDataChanged ping 并获取 userId。

使用该 userId 连接的应用程序 ping 回 SSO 并获取该特定 userId 的用户详细信息并添加到用户列表中。

这就是我所有工作的方式,所以现在我只是将我的答案标记为已接受,但正如我上面提到的那样:“这可能不是处理这个问题的完美方法,但据我所知它对我有用太好了。但是是的,我仍然愿意接受建议。”

特别感谢 @Jankapunkt 帮助我。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-07-24
    • 2013-05-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-11-29
    相关资源
    最近更新 更多