How do I login a user with devise?

27,295

Solution 1

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

sign_in(:user, user)

Solution 2

  resource = warden.authenticate!(:scope => resource_name)
   sign_in(resource_name, resource)
Share:
27,295
Matt Elhotiby
Author by

Matt Elhotiby

Interests: Javascript, React and Rails

Updated on January 29, 2020

Comments

  • Matt Elhotiby
    Matt Elhotiby over 4 years

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

    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)

    How do I fix this?

    UPDATE

    this works but seems very 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
    
  • Matt Elhotiby
    Matt Elhotiby about 12 years
    this logs them in regardless even if the password is wrong or not
  • owl
    owl about 12 years
    Check user.valid_password?(params[:password]) first, then.
  • ishwr
    ishwr over 10 years
    I tried exactly like this but got wrong number of arguments (2 for 0). any idea?
  • owl
    owl over 10 years
    @takodil Maybe that method is being defined by something else. Open a new SO question and include your code. Along with that information, show us the output of method(:sign_in).source_location in this new question as well.
  • ishwr
    ishwr over 10 years
    @RyanBigg Thank you for replying. I made a new SO question. stackoverflow.com/questions/19172935/… Can you tell me where should I put method(:sign_in).source_location ? thanks
  • Caleb
    Caleb almost 10 years
    @Trace A valid use case for signing the user in without validating the password is during a customized registration process, for example.
  • DaveMongoose
    DaveMongoose about 5 years
    What should each of these variables contain, and how do you pass in the username and password?