设计 - 为多个用户单一登录表单

Abi*_*bid 5 ruby-on-rails devise warden ruby-on-rails-3

我有两个Devise模型,User和Business; 我希望两者都能够使用单一登录形式登录.我正在使用骨干js,我有一个自定义的视图,所以视图不是一个问题.ajax请求用于登录,它按预期适用于用户,但不适用于企业.

我搜索过谷歌,并提到了一些提到使用STI来解决这个问题的解决方案,但是项目已经完成,我现在无法做出这样的改变.我正在考虑重写Devise会话控制器和:

  1. 检查给定的电子邮件地址是否为用户,然后使用Warden对用户进行身份验证.
  2. 如果未找到具有该电子邮件的用户,则使用Warden对Business模型进行身份验证.

我无法弄清楚如何更改代码来实现上述目标,我不知道warden如何工作以及我需要调整哪些params来实现上述功能,需要调用哪些函数.任何人都可以指出我正确的方向或提供一个例子,说明我应该如何向前推进.

谢谢.

Bry*_*yce 7

别担心,你不会被卡住.

我认为你最好的选择是覆盖Devise的会话控制器并改变会话的'new'和'create'方法.

所以在你自己的"sessions_controller.rb"中,你会有这样的东西:

class SessionsController < Devise::SessionsController
  # GET /resource/sign_in
  def new
    resource = build_resource(nil, :unsafe => true)
    clean_up_passwords(resource)
    respond_with(resource, serialize_options(resource))
  end

  # POST /resource/sign_in
  def create
    resource = warden.authenticate!(auth_options)
    set_flash_message(:notice, :signed_in) if is_navigational_format?
    sign_in(resource_name, resource)
    respond_with resource, :location => after_sign_in_path_for(resource)
  end
end
Run Code Online (Sandbox Code Playgroud)

在你的路线中,你会使用类似的东西(取决于你命名的用户模型):

devise_for :users, :controllers => {
    :sessions => 'sessions'
}


devise_for :businesses, :controllers => {
    :sessions => 'sessions'
}
Run Code Online (Sandbox Code Playgroud)

以上会话控制器根本不是自定义的.我不知道你的代码,所以我无法真正帮助那里.但基本步骤是:

  1. 检查auth_options和resource_name变量以了解它们如何存储数据.
  2. 如果resource在Users表中找不到,则添加条件逻辑以更改这些变量.

设计是伟大的,角色很棒,但有时候有一个用户模型,甚至使用STI,没有意义.我很快就在这个问题上写了一篇更长的帖子,因为我在最近的一个项目中处理了这个问题.


小智 5

我最近想出了这个方法来完成这项工作。我的建议是强烈考虑具有角色的单个用户模型,但这至少在当前版本的Devise中有效。

https://gist.github.com/jeremyw/5319386

如果您采用猴子补丁程序或以其他方式覆盖此类默认行为,请确保您具有良好的测试套件,以防万一想要升级Devise。


ob1*_*ob1 4

考虑仅使用 User 模型,并使用CanCan和Rolify来满足每种类型用户的独特需求。这可能意味着重新开始一些代码,但从长远来看,它可能更容易维护。

不要只相信我的话。这是一个相关的问题,有很好的回答。