使用 OpenId Connect 插件和 AWS Cognito 自动登录

你好。我是 Discourse 的新手。我在 AWS 上运行一个应用程序,该应用程序使用 Cognito 进行身份验证。我想将此应用程序与我新托管的 Discourse 论坛关联起来。我已经取得了一些进展,但我希望有人能指导我完成最后的步骤

目标是在我的应用程序和 Discourse 论坛之间实现无缝的登录体验。因此:

  • 如果用户已登录到我的应用程序,当他们访问 Discourse 论坛时,Discourse 应能识别此状态,并且不需要重新登录。

  • 同样,如果用户首次访问 Discourse 论坛且未登录,Discourse 应将其重定向到我的应用程序的登录页面(或在必要时重定向到托管的登录 UI)。

OpenId Connect 身份验证插件 似乎非常适合此场景。我已注册 Discourse 的企业版计划,以确保可以使用该插件。

我已按照 @david 提供的说明操作,并完成了我认为在 Cognito 侧的设置:

  1. 从 Cognito,我获取了“OpenID Connect 发现文档”和“OpenID Connect 客户端 ID”。

  2. 在我的 Discourse 设置中,在 openId_Connect 下,我已添加这些信息并保存。

  3. 我已勾选“启用 OpenID Connect 身份验证”,并在 OpenID Connect 授权范围中输入了“openid email”。我已保存这些设置。

根据插件描述,这应该可以正常运行了,对吗?

然而,当我登录到我的应用程序,然后前往我的论坛时,什么也没发生。它只是显示了正常的首页,并带有“注册”和“登录”按钮。我希望它在与 Cognito 检查后能自动登录我,但它没有。我还需要做什么?

此外,如果用户是首次访问论坛网站(从未登录过我的应用程序),他们不应看到 Discourse 的注册和登录按钮——相反,他们应该看到一个按钮,点击后会将其重定向到我的应用程序的登录页面。如何添加此按钮?

最后,用户订阅我的应用程序并付费使用高级功能。这些信息作为用户的自定义属性保存在 Cognito 中(有一个自定义属性表示是否已订阅)。只有已订阅的用户才能在论坛发帖。因此,当 Discourse 向 Cognito 查询用户信息时,需要检查用户的自定义属性,并且只有在用户已订阅的情况下才赋予其发帖权限。如何操作?

由于我刚开始接触 Discourse,非常感激任何人能提供关于这些问题的任何信息。谢谢!

你好 @JQ331 :wave:

仅当您的站点为私有站点(即启用了 login_required 站点设置)时,才支持自动登录。

这应该已经是当前的工作方式。请确保您已禁用所有其他登录方式,包括“本地登录”。

很遗憾,使用 OIDC 插件无法实现此功能。

@david,非常感谢您的回复,这很有帮助。

这个“login_required”站点设置在哪里?您所说的“私有”是指用户必须登录后才能查看站点内容吗?显然,这不是我想要的。我希望的是:只有登录后才能发帖,而登录的唯一方式是通过我的独立应用。

我理解您指的是在 设置 → 登录 → 启用本地登录(取消勾选此项)。我已经取消勾选了所有本地登录选项。但这里我应该勾选什么呢?例如,如果我使用插件将我的独立应用与登录功能关联,那么这个独立应用是属于“SSO”还是“OAuth2”?(我想知道是否应该选择“SSO 覆盖邮箱”或“OAuth2 覆盖邮箱”?)

关于仅允许付费用户发帖:

这是一个基本要求,所以我可能需要发挥一些创意。除了 SSO 插件之外,还有其他选择吗?如果没有,如果以下任一方案可行,我仍然认为这个方案可以运作:

  1. Discourse 是否具有不同级别的用户权限?这样我可以设置:用户虽然可以登录,但没有权限发帖或回复帖子。在这种情况下,我需要根据 Discourse 从 Cognito 获取的信息(是否已订阅)来设置用户的权限级别。

  2. 如果上述方案不可行,Discourse 是否有可用的 Stripe 插件,允许用户登录,但只有当他们在 Stripe 系统中完成付款后才能发帖?

  3. 如果以上两种方案都不可行(例如,Discourse 无法区分我可以设置的用户权限级别),那么我似乎需要让用户要么登录,要么不登录,只有登录的用户才能发帖。这样理解对吗?

如果是这样,我就需要在我的独立应用端想办法,告诉 Discourse 仅当用户在应用中已付款时才允许其登录 Discourse。

谢谢。

在这种情况下,目前尚不支持自动登录。用户必须点击登录按钮。

好的,那么现在登录按钮应该直接链接到您的身份提供商。这能正常工作吗?

是的,您可以将所有分类设置为“所有人”可读,但只有特定用户组中的成员才能创建或回复主题。如果您希望自动化这一过程,可以使用 API 将用户添加到或从用户组中移除。

太棒了——看来我离目标很近了。再确认一下:

我希望实现以下情况:

  1. 所有人都可以阅读网站内容(无论是否登录)。
  2. 只有登录用户才能发帖。
  3. 如果您已登录我的应用,当您访问 Discourse 时,系统会与 Cognito 通信,并自动为您登录,从而允许您发帖。

您是在说(3)是不可能实现的吗?您的意思是,出于某种原因,自动登录在网站内容对公众隐藏时才会发生?


这听起来正是我想做的。从您提到“使用 API”来看,我理解您的意思是:

  1. 用户尝试登录我的论坛。
  2. 他们被重定向到登录我的应用。
  3. 当他们登录我的应用后,我的应用会检查他们是否已付费。如果已付费,我的应用将调用 Discourse API 将该用户添加到拥有发帖和回复权限的“组”中。

我的理解对吗?如果是这样,是否有推荐的文档,说明如何通过 API 将用户添加到组中?

谢谢,这真的帮了我大忙。

我想我们可能对“自动登录”的定义有所不同。

Discourse 可以连接到 OIDC 提供商进行登录。该过程在用户点击论坛上的“登录”按钮时启动。无论配置如何,这始终有效。

如果站点要求登录(即启用了“需要登录”设置),则用户会被直接重定向到 OIDC 登录界面,无需点击按钮。

是的,我想表达的就是这个意思。这里有相关文档 介绍该 API 端点。

好的,谢谢!我会查看那份 API 文档。听起来非常有前景。

关于“自动登录”这一点——似乎您的意思是“自动登录 = 自动将用户重定向到登录页面”。所以,您的意思似乎是:当用户访问我的 Discourse 论坛时,有两种选择:

选项 1:网站“自动”将他们重定向到独立的应用程序登录页面。无论用户是否已登录我的应用程序,都会发生这种情况。(这就是您所描述的“自动登录”,您提到如果设置了 login_required,就会发生这种情况。)

选项 2:网站不进行任何自动重定向。相反,页面上有一个基本的登录按钮。如果用户点击该按钮,或尝试发帖,论坛会将他们重定向到我的应用程序的登录页面。

我原本希望的是选项 3:如果用户已登录我的应用程序,当他们访问我的 Discourse 论坛时,我的 Discourse 论坛会向 Cognito 查询用户是否已登录。如果用户已登录 Cognito,则 Discourse 会直接将他们登录到论坛,无需用户再次单独登录

我对 OpenID 还不太熟悉,但我确实认为这是可行的,因为如果用户在两个平台之间切换时需要分别登录应用程序和论坛,那将不是一种无缝的体验。

难道没有一种方法可以让 Discourse 论坛与 Cognito 进行通信,并在用户无需经历单独登录流程的情况下调整其登录状态吗?

顺便提一下,我假设直接将 Discourse 集成到我的应用程序中可能没有帮助。如果可以的话,我当然会这样做,但看起来这只能通过 iframe 实现,而这无法解决身份验证问题。

这在 OIDC 规范中技术上可行,但不幸的是,Discourse 目前尚不支持该功能。

嗯。我听说在 Discourse 和像 Cognito 这样的独立身份验证提供商之间建立链接有两种方法:使用 OpenID 插件,或者为 Discourse 使用 单点登录 (SSO)

我对单点登录流程完全不熟悉,但这是否能实现我的目标——避免用户重复登录?

或者,也许只需在用户登录我的应用时,向 Discourse 发送一个 API 调用,从而为他们自动登录?

(我链接的文档中也提到了指定组成员资格——我推测这应该能实现我的目标,即只有付费用户才能加入被允许发帖的群组。)