Wordpress 多站点配合多个 Discourse 实例

大家好,

我想了解在当前架构中增加另一个 Discourse 社区的技术可行性。目前,我们使用的是 WordPress 多站点(Multisite)架构,其中有一个 Discourse 社区通过 Discourse SSO 与一个专门用于该社区的站点集成,而 WordPress 的登录则由另一个 SSO 提供商提供支持。

我计划为一个新的 Discourse 社区创建一个新的 WordPress 站点,但不清楚在这样的多站点架构中,是否可以将多个 Discourse 论坛整合在一起(如果这样表述清楚的话)。由于 SSO 是基于 WordPress 网络(Network)设置的,似乎无法支持多个 Discourse 实例。

理想情况下,我们希望实现:

  • WordPress 多站点
  • 两个 Discourse 实例

(两个 Discourse 实例之间的用户应仅能访问其所属的社区)。

我查阅了一些关于“WordPress 多站点配合单实例 Discourse”(或反之)的帖子,但尚未找到关于“WordPress 多站点配合多个 Discourse 实例”的相关资料。

谢谢。

在 WordPress 多站点设置中,无法让各个站点作为两个 Discourse 实例的 SSO 提供商。原因是,在多站点网络中,所有用户都存储在单个数据库表中。如果允许多个 Discourse 站点作为网络中多个站点的 SSO 提供商,则无法以直接的方式保证保存在 WordPress 上的 Discourse 用户 ID 是唯一的。

谢谢——这正是我猜测的情况。是否可以让一个 Discourse 实例作为另一个实例的 SSO 提供商,同时确保用户能够正常访问各自社区?

一个 Discourse 实例确实可以作为另一个 Discourse 实例的 SSO 提供商。我推测您考虑的架构是:WordPress 作为 Discourse 实例 1 的 SSO 提供商,而 Discourse 实例 1 再作为 Discourse 实例 2 的 SSO 提供商。我认为这在理论上是可行的,但我从未配置过 Discourse 站点同时作为 SSO 客户端和 SSO 提供商。

按照上述架构,Discourse 实例 1 上的所有用户都将能够访问 Discourse 实例 2。我想这并不是您想要的结果。

解决该问题的另一种可行方案是:只使用一个 Discourse 实例,并利用分类组权限来限制用户可访问的论坛部分。您可以在 SSO 负载中传递 Discourse 用户组。在您的 WordPress 站点上,应该可以确定用户有权访问哪些站点。您可以为每个 WordPress 站点创建一个 Discourse 用户组,然后使用 wpdc_sso_params 过滤器,向 SSO 负载中添加一个 add_groups 参数。

目前 Discourse SSO 是 SSO 提供商——我猜(新的)考虑方案是将实例 1 作为 SSO 提供商(同时服务于实例 1 和实例 2)。

本质上,保持我们当前的 SSO 设置不变,但增加另一个 Discourse 实例,同时仍然以某种方式限制实例 1 和实例 2 之间的访问。

你好 @simon,目前正在实施此功能,但我不确定为什么在 WP Discourse 插件中看不到 SSO 客户端选项。请参见下方的截图:

我的连接显示为活跃状态(API 密钥的最后使用时间也证明了这一点)。在添加 [discourse_sso_client] 短代码时,似乎存在配置问题(位置响应头中包含的是由 [discourse_sso_client] 短代码生成的 URL,而不是 SSO 负载。

这是有意为之。SSO 客户端选项仅在多站点网络中且在全站级别配置时才可用。我需要在本地开发环境中搭建一个多站点网络,以再次检查相关设置。我今天晚些时候会再向您反馈。

谢谢——目前我在网络级别安装了该插件,并选择了 SSO 客户端。

编辑:我已将问题定位到这里的 query-redirect.php

if ( empty( $this->options['sso-client-enabled'] ) || 1 !== intval( $this->options['sso-client-enabled'] ) ) {
   return;
}

看起来这个选项对我来说没有被正确设置——不确定是网络级别的设置问题还是其他原因。

关于在 multisite 网络中设置该插件的文档已过时。这是一个整理并更新 WP Discourse 插件安装与设置 指南的好机会。

要在 multisite 网络上使用 SSO 客户端功能,需要在网络级别配置该插件。这可以通过点击网络仪表板上的 Discourse 链接来完成:

在 Discourse 网络页面上,选择“启用 multisite 配置”选项。然后在“连接设置”部分输入您的 Discourse URL、API 密钥和发布用户名。滚动到页面底部并点击“保存选项”按钮。您应该在页面顶部看到“您已连接到 Discourse!”的消息。

要将 Discourse 用作您 multisite 网络上各站点的 SSO 提供商,请滚动到 Discourse 网络页面底部,选择“启用 SSO 客户端”选项。同时,在 SSO 密钥设置中添加一个密钥。再次保存您的选项。

现在,前往您的 Discourse 站点,将密钥复制到 Discourse 的 sso provider secrets 站点设置中。在 SSO 提供商域名中输入 * 符号。保存该设置后,它应类似于以下内容:

现在在 Discourse 上选择“启用 SSO 提供商”选项。

设置好这些配置后,访问您网络上任何站点的 WP Discourse SSO / SSO 客户端标签页,应该会显示类似于以下的页面:

为了快速测试,请选择“添加登录链接”和“按邮箱同步现有用户”选项。然后退出您的 WordPress 站点。您应该能够通过点击显示在 wp-login.php 页面上的“使用 Discourse 登录”链接重新登录。

如果您未使用默认的 WordPress 登录页面,可以尝试将 [discourse_sso_client] 短代码复制到您站点的一篇帖子中。该短代码仅对未登录用户显示页面标记。您也可以通过构造如下形式的链接来创建登录链接:

<a href="https://example.com/?discourse_sso=1&redirect_to=https://example.comt/">Log in with Discourse</a>

这将使用 Discourse 将用户登录到您的站点,然后将其重定向回您设置为 redirect_to 参数值的 WordPress 页面。

根据您的调试结果,似乎您的 Discourse 网络页面上未启用“启用 SSO 客户端”选项。请确保该选项已启用,并告知我们是否仍存在问题。

您发现的阻止 SSO 客户端正常工作的代码是正确的,但其条件语句编写不当:

if ( empty( $this->options['sso-client-enabled'] ) || 1 !== intval( $this->options['sso-client-enabled'] ) )

应简化为 if ( empty( $this->options['sso-client-enabled'] ) )。这是插件中其他位置使用的模式。