bamthomas
(Bruno Thomas)
1
我们使用 Discourse 作为协作工具,并拥有另一个用于搜索文档的应用 Datashare。我们希望将关于文档的评论集成到 Discourse 中。两者都在我们的基础设施内使用外部 SSO/OAuth 提供商。
我们使用用户 API 密钥来连接这两个应用,以便它们能够通信。这可以正常工作,但我们不得不点击“授权应用访问”表单,而我们希望避免这一操作,因为我们的环境是基于 OAuth 的可信环境。
是否有办法跳过或绕过这个“授权”访问步骤,直接进入用户 API 密钥的创建流程,从而不显示该页面,让用户无需执行这一额外步骤?我们是否可以在请求中提供某个参数来绕过此步骤?
我们尝试先调用 UserApiKeysController.create(而不是 UserApiKeysController.new),但遇到了 CSRF 错误。因此,我们尝试跳过令牌验证,如下所示:
class UserApiKeysController < ApplicationController
skip_before_action :verify_authenticity_token
end
但这也不起作用。
您是否有其他实现方式?
提前感谢。
osioke
(Osioke Itseuwa)
2
欢迎加入,Bruno,很高兴你来到这里
也许 @david 或 @blake 对此有一些想法。
riking
(Kane York)
3
我可以肯定地说,这并不是正确的做法。你已经在用插件了吗,还是仅通过 HTTP 进行交互?
如果你正在使用插件,在大多数情况下,你不应该与 app/controllers/ 中的实例进行交互。
如果你通过 HTTP 进行交互,并且使用的是服务器到服务器的通信,那么使用由管理员创建的 API 密钥会是更好的选择。
用户 API 旨在用于客户端到服务器的通信,在这种场景下,无法在客户端层面提供代码完整性保障。
bamthomas
(Bruno Thomas)
4
是的,我们计划开发一个 Discourse 插件,我们的 JS 应用将仅通过 HTTP 请求进行交互。
我们希望避免开发服务器对服务器的通信(例如使用管理员 API 密钥),以尽量减少组件之间的耦合。
我理解理想情况下我们不应直接修改 Discourse 的控制器,但同时,确实有很多方法似乎被设计为可被重写(模板方法模式及其他扩展点),而且据我们目前所见,许多插件确实是这样做的。
那么,正确的做法是什么呢?
riking
(Kane York)
5
如果你正在编写一个插件,应该在插件挂载的控制器中开发新的路由,直接执行你需要的任务。这些路由可以共享一个 before_action,用于设置 Access-Control-Allow-{Origin, Headers, Credentials} 响应头(如果 Origin 请求头中的域名在你的应用允许运行的域名列表中,则将其回显)。
这样,你的 JavaScript 代码只需调用 fetch(..., { credentials: "include", ...}),完全不需要 API 密钥。
bamthomas
(Bruno Thomas)
6
感谢 @riking,当我们在导航器中拥有 Discourse 的开放会话时,这确实有效。
由于我们设置了 SiteSetting.enable_local_logins = false 且仅使用 OAuth 一种认证机制,我们可以通过手动访问 http://discourse_site/login 来发起新会话。浏览器会跟随重定向跳转到我们的 OAuth 提供商,然后再重定向回 Discourse。这正是调用 /user-api-key/new 时在后台发生的情况。
那么,如果当前没有会话,我们如何从应用程序中编程方式发起新的 Discourse 会话呢?