干得漂亮,能想到这一步 ![]()
我不想贬低你已经完成的工作,但我初步的看法是,你现在应该考虑使用外部认证服务(例如 okta.com 或 auth0.com)。当你需要连接三个不同的服务(例如 Patreon、WordPress 和 Discourse)来实现一次性统一认证时,这就表明你应该考虑采用专门的认证解决方案。无论你是否能以某种方式实现,这里都存在相当大的长尾风险:你的解决方案可能会失效,或者无法在所有情况下正常工作。
如果你仍然想走这条路,我有一些建议,但事先声明,接下来会涉及一些技术细节。我之所以把这些写在这里,部分原因是希望其他遇到同样问题并希望进一步探索的人也能看到。
我快速查看了一下 Patreon WordPress 插件代码,发现他们的 OAuth 流程在 state 参数中接受一个 final_redirect_uri 键值对。这将允许你直接从 Patreon 认证跳转到 Discourse SSO,从而无需上述的 Members 和 Redirect 插件,并避免该方案可能引发的任何问题。
许多认证服务都有类似 final_redirect_uri 的参数,即允许你更改用户认证后被重定向到的位置。如果你是因为试图解决相同问题(但使用的是其他服务,而非 Patreon)而阅读此内容,并且你也认为我关于“不要连接三个不同服务”的警告不适用于你的情况,那么你应该去查找这类参数。
这意味着你需要让生成 Patreon 登录按钮的短代码接受 final_redirect_uri 作为参数,然后将其传递给 Patreon 最终使用的登录 URL。查看 Patreon WordPress 插件代码,这完全是可行的。为了让你有个概念,生成 Patreon URL 的相关函数大致如下:
Patreon_Frontend::patreonMakeLoginLink(false, array( 'final_redirect_uri' => # ) );
基本上,代码已经部分配置好以处理自定义的 final_redirect_uri。我能理解 Patreon WordPress 插件的开发者可能不想添加此功能,但如果你觉得自己有能力清晰描述我上面所说的内容,那么在他们 GitHub 仓库 上提一个 issue 可能是值得的。如果不行,你可以使用我上面提到的那个函数自己生成链接并创建按钮(或者聘请一位 WordPress 开发者来帮你做)。
关于 SSO URL 的构建,这里有个小建议:使用以下格式会更清晰:
https://discourse.example.com/session/sso?return_path=/
而不是:
https://discourse.example.com/session/sso?return_path=%2F
最后那部分 return_path 是用户登录后在 Discourse 中被重定向到的路径。如果是 /,他们将被送往论坛首页。有关 SSO URL 构建的更多信息,请参阅 WP Discourse 技巧与窍门。