riverrun/comeonin

Migration from Devise

brandonparsons opened this issue · 4 comments

Hi there,

I'd like to use comeonin for a port of an app I'm moving over from Rails. My passwords are currently hashed by Rails using Devise. Is it possible to migrate over directly, or convert the passwords somehow?

Each password hash should have the necessary information contained within it, and you should have no problem using Comeonin to check passwords used in your Rails app.

Having Devise check the password hashes generated by Comeonin is a little more complex, but is possible.

If you could provide me with an example password hash generated using Devise, I can give you some more advice.

@riverrun Hi there - thanks for getting back to me!

Luckily it seems like I'm on the easier end of the bargain. I'm hoping that I can just move the database over to the new app using Comeonin. Then when users attempt to log in, I'd use Comeonin to check the password against the Rails/Devise hash, and if successful, write a new hash generated by Comeonin's default algorithm and use that from then on. Hopefully the whole process would be transparent to my end users.

Here's some example data from the current Rails/Devise implementation:

u = User.first
u.update password: "asdfasdf", password_confirmation: "asdfasdf"

u.encrypted_password
=> "$2a$10$VRqlEG1zAldYrjQSR3gACuxbb4QFVTzq2QWEq369eINekOKrpIseK"

So hashing asdfasdf in my current Rails app gets us "$2a$10$VRqlEG1zAldYrjQSR3gACuxbb4QFVTzq2QWEq369eINekOKrpIseK".

I suppose I'm after something like the following in my new Elixir app (pseudo-code):

u = %User{....}
attempted_password = "asdfasdf"
current_hash = u.old_encrypted_password # "$2a$10$VRqlEG1zAldYrjQSR3gACuxbb4QFVTzq2QWEq369eINekOKrpIseK"

if Comeonin.validate_old_brcypt_2a_hash(attempted_password, current_hash) do
  User.sign_in(user) # ......
  User.set_new_encrypted_password( Comeonin.hashpwsalt(attempted_password) )
else
  User.failed_login(user)
end

That pseudo code looks fine. A couple of comments:

  1. You can use the regular Comeonin.Bcrypt.checkpw(attempted password, current_hash) function - it can check both the '2b' and '2a' hashes
  2. If the hashes in your database also start with '$2a$10$', this indicates that the number of rounds is 2^10, which on current hardware is probably too low, so creating a new hash with Comeonin.Bcrypt.hashpwsalt is probably well worth it (the default number of rounds for Comeonin.Bcrypt is 12).

If you have any further questions, just let me know.