我正在为我的应用程序创建API。一方面,有API服务器(和主应用程序),另一方面是客户端。服务器使用DoorKeeper使用OAuth 2.0保护API(基本上将主应用程序转换为OAuth 2.0提供程序),客户端使用OmniAuth为我的应用程序设置自定义策略。
主应用程序使用子域名进行多租户;所以每个客户都有自己的子域名。还有一个oauth
子域,它被路由到DoorKeeper接口。
当用户点击“使用我的应用登录”链接时,他会被重定向到oauth子域。如果他未登录主应用程序,则需要将其重定向到正确子域下的登录页面。所以我需要将客户端的帐户名传递给服务器,以便DoorKeeper知道要重定向到哪个子域。
我怎样才能实现这一目标?
我已经研究了这个主题,并找到了如何传递给将传递给回调动作的OmniAuth参数。这些参数是否可供服务器使用?
编辑:我没有使用Devise!
编辑2 :这是一些代码。
客户端应用会话控制器创建操作(使用我的应用登录)def set_client
self.current_client = Client.find(params[:client][:name])
redirect_to "/auth/catapult?client=#{self.current_client.account_name}"
end
如您所见,我将客户端参数附加到OmniAuth路由,但此参数未传递到服务器应用程序(DoorKeeper),因此我不知道在服务器应用程序上重定向到何处。
DoorKeeper配置resource_owner_authenticator do
p params
User.find_by_id(session[:user_id]) || redirect_to(log_in_path)
end
在上面的重定向中,我需要将客户端的帐户名称指定为子域名,但我没有此信息(客户端的帐户名称),因为params哈希不包含我传递的客户端帐户名称(客户端) PARAM)
答案 0 :(得分:3)
我发现了如何解决我的问题。我不得不深入研究OmniAuth源代码。我必须做的是覆盖我的自定义策略中的request_phase
方法,如下所示:
def request_phase
redirect client.auth_code.authorize_url({:redirect_uri => callback_url, :catapult_client => request.params["client"]}.merge(authorize_params))
end
:catapult_client
在哪里,添加你想传递的任何额外的参数,它就可以了!
答案 1 :(得分:1)
最简单的方法是在重定向到登录页面时将地点重定向到验证后成功作为查询参数传递,因此它作为GET请求的查询字符串的一部分存在。存储它,并在成功的身份验证中,将它们重定向到那里。您根本无需将此数据包含在OAuth流程中。
当然,我假设他们所有都在他们的子域开始。
编辑:
当用户点击“使用我的应用登录”链接时,他会被重定向到oauth子域。
假设用户从mysubdomain.yourapp.com
开始,他们点击“使用我的应用登录”链接。
该链接还包含一个包含子域名的查询参数,因此oauth.yourapp.com?redirect=mysubdomain.yourapp.com
(或仅oauth.yourapp.com?redirect=mysubdomain
)
用户到达oauth.yourapp.com。该应用程序存储查询参数。用户输入他们的详细信息或重定向到服务...
OAuth流程已完成,用户已通过身份验证。
将用户重定向回早先存储的redirect
参数。
这就是我这样做的方式,只是没有使用Rails,但我不明白为什么你不能在任何框架中使用这个过程。正如我所提到的,这取决于用户从正确的子域开始。