Devise: manually encrypt password and store directly

前端 未结 5 936
[愿得一人]
[愿得一人] 2021-02-01 02:27

I\'m trying to migrate a ton of users from an old database. To do this, I\'m using activerecord-import and trying to save all my user data directly to DB (bypassing the User mo

相关标签:
5条回答
  • 2021-02-01 02:52

    An alternative method is: User.new.send(:password_digest, 'xxx')

    0 讨论(0)
  • 2021-02-01 02:57

    Good news and bad news.

    Good news:

    The following works to create your user's password manually.

     pepper = nil
     cost = 10
     encrypted_password = ::BCrypt::Password.create("#{password}#{pepper}", :cost => cost).to_s
    

    You can find your pepper and cost in your devise initializer. This method was confirmed using Devise's "valid_password?" method.

    Bad news:

    The entire reason I was trying to avoid "User.new(password: password).encrypted_password" was because of speed. It's terribly slow. With all my other pieces of my import task, I've intentionally avoided this.

    But as it turns out, the major cost here is not instantiating a User object -- but BCrypt itself. There is very little noticeable speed boost when using BCrypt directly because it's intentionally designed to be slow.

    My final answer: suck it up, run the rake script, go find a beverage.

    0 讨论(0)
  • 2021-02-01 02:58

    None of the other answers above worked for me, so here is what I did:

    user.valid_password?(plain_password)

    https://github.com/plataformatec/devise/blob/d293e00ef5f431129108c1cbebe942b32e6ba616/lib/devise/models/database_authenticatable.rb#L44

    0 讨论(0)
  • Assuming you have a mysql database with a "users" table and a "password" column And an ActiveRecord model class called "user" that is hooked up to devise

    Create an ActiveRecord model class in your app app/models/old_user.rb

    OldUser < ActiveRecord::Base
      set_table :users
      establish_connection :database => "old_database", :user => "old user", :adapter => "mysql"
    end
    

    then create a rake task: app/lib/tasks/migrate_users.rake

    task :migrate_users => :environment do
      OldUser.find_each do |old_user|
        u = User.new(:email => old_user.email, :password => old_user.password, :password_confirmation => old_user.password);
        #if your using confirmation
        u.skip_confirmation!
        u.save!
      end
    end
    

    Modify as necessary (make sure you're saving any app-specific user attributes)

    Then$ rake migrate_users

    0 讨论(0)
  • 2021-02-01 03:14

    You should do it like this:

    password = 'the secret password'
    new_hashed_password = User.new(:password => password).encrypted_password
    

    This is much better than using BCrypt directly as it abstracts away how passwords are generated from your code, making it easier to understand, and also immune to changes in how devise constructs encrypted passwords. Your code should not, and has no reason to know anything about that.

    0 讨论(0)
提交回复
热议问题