Rails 3和Devise:在执行POST操作时验证用户

使用Rails 3.0.6,Omniauth 0.2.0和Devise 1.2.1,我遇到以下情况: 我想为用户提供通过Facebook进行身份验证的选项。我使用Devise设置了用户系统,我可以使用Facebook成功验证。我花了几个小时试图编写一个特定情况下我想要的行为: 用户未登录 用户拥有一个站点帐户 用户通过Facebook验证 此时我为用户提供2种选择 创建一个帐户(可以是没有提供信息的虚拟帐户) 将此Facebook身份验证与现有帐户相关联 我遇到了后一个选项的问题。用户已经过身份验证,但我仍然需要他使用他的网站帐户登录。我在我的
AuthenticationsController
中有一个操作,它会将此身份验证与登录用户关联起来。尽管如此,Devise似乎并没有为我提供一种方法来记录用户同时保持相同的操作。这是我第一次尝试这样做
class AuthenticationsController < ApplicationController
  before_filter :authenticate_user!, :only => :auth_link_existing_user

  ...

  def auth_link_existing_user
   ...
  end
但是,使用此方法,如果用户登录,则只需将其重定向到我站点的根页面。我知道我可以更改Devise的登录重定向,但这将适用于所有登录。我只希望这种情况有一个单独的重定向。 阅读完这个邮件列表问题后,我尝试用自己的自定义行为扩展
SessionsController
def create
  resource = warden.authenticate!(:scope => resource_name, :recall => "#{controller_path}#new")
  set_flash_message(:notice, :signed_in) if is_navigational_format?
  sign_in(resource_name, resource)
  if params[:redirect]                            #new
    redirect_to params[:redirect].to_sym          #new
  else
    respond_with resource, :location => redirect_location(resource_name, resource)
  end

end
这也不起作用。我已经定义了我的
auth_link_existing_user
路线以使用POST动词(看起来准确),重定向只能是GET。 所以现在我确实有一个解决方案:将Devise的
authenticate_user!
帮助器中的代码复制并粘贴到一个新函数中,该函数可以在控制器操作中调用而无需重定向。这对我来说似乎不太理想,因为它是代码的重复并增加了耦合 - 改变这种行为的Devise或Warden更新也会破坏我的代码。 有没有其他人尝试这样的东西,并提出一个更优雅的解决方案?您是否看到我向用户提供此类或类似行为的更简单方法? 更新:对于任何想在最后使用我的脏解决方案的人来说,这就是我所做的:
def auth_link_existing_user
  # FROM Devise/sessions/create
  resource = warden.authenticate!(:scope => :user, :recall => "registrations#auth_new")
  set_flash_message(:notice, :signed_in) if is_navigational_format?
  sign_in(:user, resource)

  # method defined in Ryan Bates' Railscast for Omniauth w/Devise
  current_user.apply_omniauth(session[:omniauth])
  current_user.save
end
请注意,此操作必须放在会话控制器中。如果没有,Warden会给你一个“无效的电子邮件/密码”错误。找到源代码是一个非常长的调试过程。 有了这个,我使用登录表单在用户进行身份验证后提交到此操作。     
已邀请:
我喜欢你的解决方案有多干净,尽管它更深入到堆栈中。 以下是我通过遵循Devise wiki上的Devise + Omniauth Facebook示例并修改
facebook
方法以将会话信息传递给Login表单来实现类似的方法,具体如下:
if @user.persisted?
    flash[:notice] = I18n.t "devise.omniauth_callbacks.success", :kind => "Facebook"
    sign_in_and_redirect @user, :event => :authentication

else
    session["devise.facebook_data"] = request.env["omniauth.auth"]
    redirect_to new_user_session_url
end
然后,在您的情况下,我将检查
session["devise.facebook_data"]
的登录控制器操作,提交带有表单的uid +令牌和apply_omniauth(如果存在)。     

要回复问题请先登录注册