如何使用devise登录用户?

时间:2012-02-18 16:21:25

标签: ruby-on-rails ruby ruby-on-rails-3 devise warden

我有我的rails应用程序,我遇到了一个设计的主要问题。我有一个控制器:

class Users::SessionsController < Devise::SessionsController
  prepend_before_filter :require_no_authentication, :only => [ :new, :create ]
  include Devise::Controllers::InternalHelpers

def new
    clean_up_passwords(build_resource)

    respond_to do |format|
      format.html { render :layout => "sessions" }
      format.mobile
    end
  end


    # POST /resource/sign_in
    def create
      resource = User.find_by_email(params[:user][:email])  
      resource = warden.authenticate!(:scope => resource_name, :recall => "#{controller_path}#new")
      set_flash_message :notice, :signed_in
      sign_in_and_redirect(resource_name, resource)
    end

end

问题是它从不记录用户,它始终在此行停止

resource = warden.authenticate!(:scope => resource_name, :recall => "#{controller_path}#new")

我甚至在实际的宝石文件中放了大量的记录器,看看我是否可以看到任何东西但没有任何东西,我真的不知道如何解决这个问题。如果我注释掉这一行,那么用户就会登录但如果电子邮件不在数据库中并且适用于任何密码(这绝对不是正确的解决方案),则会失败

我该如何解决这个问题?

更新

这有效,但似乎非常hackish

# POST /resource/sign_in
def create
  resource = User.find_by_email(params[:user][:email])

  redirect_to(new_user_session_path, :notice => 'Invalid Email Address or Password. Password is case sensitive.') and return if resource.encrypted_password.blank?      
  bcrypt   = BCrypt::Password.new(resource.encrypted_password)
  password = BCrypt::Engine.hash_secret("#{params[:user][:password]}#{resource.class.pepper}", bcrypt.salt)
  valid = Devise.secure_compare(password, resource.encrypted_password)
 # resource = warden.authenticate!(:scope => resource_name, :recall => "#{controller_path}#new")
  if valid
    set_flash_message :notice, :signed_in
    sign_in_and_redirect(resource_name, resource)
  else
    redirect_to(new_user_session_path, :notice => 'Invalid Email Address or Password. Password is case sensitive.') and return    
  end

end

4 个答案:

答案 0 :(得分:74)

如果您想登录用户,请使用控制器操作中的sign_in帮助:

sign_in(:user, user)

答案 1 :(得分:2)

  resource = warden.authenticate!(:scope => resource_name)
   sign_in(resource_name, resource)

答案 2 :(得分:0)

我发现这篇文章对于设置请求规范的登录非常有用。 https://makandracards.com/makandra/37161-rspec-devise-how-to-sign-in-users-in-request-specs

module DeviseRequestSpecHelpers

  include Warden::Test::Helpers

  def sign_in(resource_or_scope, resource = nil)
    resource ||= resource_or_scope
    scope = Devise::Mapping.find_scope!(resource_or_scope)
    login_as(resource, scope: scope)
  end

  def sign_out(resource_or_scope)
    scope = Devise::Mapping.find_scope!(resource_or_scope)
    logout(scope)
  end

end

将其包含在spec_helper

RSpec.configure do |config|
  config.include DeviseRequestSpecHelpers, type: :request
end

根据需要登录

sign_in create(:user, name: 'John Doe')

答案 3 :(得分:0)

以下是标准create动作的工作原理:

  # POST /resource/sign_in
  def create
    self.resource = warden.authenticate!(auth_options)
    set_flash_message!(:notice, :signed_in)
    sign_in(resource_name, resource)
    yield resource if block_given?
    respond_with resource, location: after_sign_in_path_for(resource)
  end

https://github.com/plataformatec/devise/blob/master/app/controllers/devise/sessions_controller.rb#L18