17

I need to do something like this from Rails console to do some testing and experiments:

User.authenticate(username, password)

I'm using Devise, but I have no idea how to do this.

I saw this other answer here

How to sign in a user using Devise from a Rails console?

But I need something cleaner and more direct. If necessary, I just need the algorithm to hash an attempted password with the salt and compare it to the encryped_password.

Is it this?

User.find(1).valid_password?('password123') 
Community
  • 1
  • 1
dan
  • 43,914
  • 47
  • 153
  • 254
  • How do you authenticate users in your sessions_controller create method? (or whatever controller and action users hit to sign in) – tybro0103 Jul 17 '11 at 14:54
  • I replaced warden.authenicate! with my own code that uses the User.find_by_username( ).valid_password?() method. – dan Jul 17 '11 at 15:25
  • 6
    It's crazy how many layers of indirection there is in Devise for stuff that used to be pretty clear and simple. – dan Jul 17 '11 at 15:26

2 Answers2

30

General info:

Check out the Devise README found here.

As an example, here is a helper method that you can use to do this test:

class User
    def self.authenticate(username, password)
        user = User.find_for_authentication(:username => username)
        user.valid_password?(password) ? user : nil
    end
end

Testing it, I get:

1.9.3p194 :001 > user = User.find(1)
    User Load (0.2ms)  SELECT `users`.* FROM `users` WHERE `users`.`id` = 1 LIMIT 1
    User id: 1, {...USER DETAILS SHOWN HERE...}
1.9.3p194 :002 > user.valid_password?('is this it?')=> false

Also working: User.find(1).valid_password?('1') in Rails console:

1.9.3p194 :011 > User.find(1).valid_password?('1')
    User Load (0.3ms)  SELECT `users`.* FROM `users` WHERE `users`.`id` = 1 LIMIT 1
    => false

For reference, here's my Devise setup for the User model:

class User < ActiveRecord::Base`

  devise :database_authenticatable, :registerable, :timeoutable, :recoverable, :rememberable, :trackable, :validatable

  {...}

end

Like you said in the comments, there is no sessions_controller since Devise. Look into the Devise config file in /config/initializers/devise.rb. Depending on your application configuration, you may also want to look at the token.rb and session_store.rb initializer configs.

EDIT: Can you check your user model to see if devise is properly configured for it? Compare it against my devise line. The :validatable property could be missing.

EDIT 2: Added the helper method to do this test if you want to do it outside of the console. Check up top.

Side-note: The rails_admin gem is pretty useful and may be worth checking out!

Hope that helps.

sbolel
  • 3,486
  • 28
  • 45
  • 1
    One caveat I would give on this answer - it seems to bypass 'paranoid' mode, if you've enabled that in the devise config. I've not yet been able to find a better way to do it, though. – DaveMongoose Mar 15 '19 at 11:40
  • 1
    I appreciate that, just thought I'd add the comment so that future readers are aware :-) For what it's worth, everything here is still accurate! – DaveMongoose Mar 26 '19 at 10:43
  • Awesome, thank you for confirming that @DaveMongoose I wasnt sure, I've been out of the RoR loop for a while now. – sbolel Mar 26 '19 at 16:53
5

I think implement can be much simpler without using any kind of gem. At least we know the email id.

email : 'currentuser@email.com' Current password: 'rubyuser'

user = User.find_by_email('currentuser@email.com')

user.valid_password?('wrong_password')  #returns false
user.valid_password?('rubyuser')    #returns true 
Ajay
  • 4,199
  • 4
  • 27
  • 47
  • 3
    I'm not sure how this method is simpler. It looks the same as what I posted above except not wrapped in a helper. Also, how is this "without using any kind of gem"? You're also using Devise (right?), which is the only gem we're all talking about. Haha, I realize its been quite a while since these were posted (plus I haven't looked at rails in some time) so I appreciate any clarification. Thanks! – sbolel Feb 03 '17 at 05:49
  • Also works for Sorcery (hope this helps searchers find this faster than I did). – JosephK Dec 30 '17 at 10:11