Ruby-on-rails 如何使用设备登录用户?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/9342832/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-03 02:51:27  来源:igfitidea点击:

How do I login a user with devise?

ruby-on-railsrubyruby-on-rails-3devisewarden

提问by Matt Elhotiby

I have my rails application and I am running into a major issue with devise. I have a controller:

我有我的 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

The problem is it never logs the user in, it always stops at this line

问题是它从不登录用户,它总是停在这一行

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

I even put tons of loggers in the actual gem files to see if I could see anything off but nothing and I really have no idea how to fix this. If I comment this line out then the user gets logged in but fails if the email is not in the db and works for any password (which is definitely not the right solution)

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

How do I fix this?

我该如何解决?

UPDATE

更新

this works but seems very hackish

这有效,但似乎很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

回答by Ryan Bigg

If you want to sign in a user, use the sign_inhelper inside your controller's action:

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

sign_in(:user, user)

回答by Mike

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

回答by Clam

I found this post useful for setting up a login for request specs. https://makandracards.com/makandra/37161-rspec-devise-how-to-sign-in-users-in-request-specs

我发现这篇文章对于为请求规范设置登录很有用。 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

Include it in your spec_helper

将其包含在您的 spec_helper 中

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

And sign in as needed

并根据需要登录

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

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

回答by Artur Beljajev

Here is how standard createactions works:

以下是标准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

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