Подтвердить что ты не робот

Придумайте: вручную шифруйте пароль и храните непосредственно

Я пытаюсь перенести тонну пользователей из старой базы данных. Для этого я использую activerecord-import и пытаюсь сохранить все свои пользовательские данные непосредственно в DB (минуя модель User).

Моя проблема: мне нужно взять старый пользовательский текстовый пароль, зашифровать его и сохранить непосредственно в БД. Я знаю, как сгенерировать пароль с помощью Devise, но мне интересно, есть ли способ получить хешированный пароль, который я могу хранить непосредственно в базе данных.

В надежде сделать:

new_hashed_password = Devise.awesome_encrypting_method(old_user.password)

Затем сохраните "new_hashed_password" непосредственно в БД без прохождения модели. Я выкопался в Devise и нашел это:

def password_digest(password)
  ::BCrypt::Password.create("#{password}#{self.class.pepper}", :cost => self.class.stretches).to_s
end

@@растягивает по умолчанию 10 (lib/devise.rb: 71) и не переопределяется моим инициализатором

@@pepper по умолчанию nil (lib/devise.rb: 148) и не переопределяется моим инициализатором

Я думал, что могу вручную создать пароль password_digest(), но я думаю, что мне не хватает чего-то фундаментального в Bcrypt, потому что даже при установке пароля и растяжек результирующий хеш каждый раз отличается.

Любые идеи? Спасибо за вашу помощь!

4b9b3361

Ответ 1

Хорошие новости и плохие новости.

Хорошие новости:

Ниже описано, как создать пароль пользователя вручную.

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

Вы можете найти свой перец и стоимость в инициализаторе вашего проекта. Этот метод был подтвержден с помощью Devise "valid_password?" Метод.

Плохая новость:

Вся причина, по которой я пытался избежать "User.new(пароль: пароль).encrypted_password", был из-за скорости. Это ужасно медленно. Со всеми моими другими частями моей задачи импорта я намеренно избегал этого.

Но, как выясняется, главная стоимость здесь не создает экземпляр объекта User, а сам BCrypt. При использовании BCrypt очень мало заметного повышения скорости, потому что он намеренно предназначен для медленного.

Мой окончательный ответ: сосать его, запустить rake script, пойти найти напиток.

Ответ 2

Вы должны сделать это следующим образом:

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

Это намного лучше, чем использование BCrypt напрямую, поскольку оно абстрагирует, как генерируются пароли из вашего кода, что упрощает его понимание, а также невосприимчивость к изменениям в том, как devits строит зашифрованные пароли. Ваш код не должен и не должен знать об этом.

Ответ 3

Альтернативный метод: User.new.send(:password_digest, 'xxx')

Ответ 4

Предполагая, что у вас есть база данных mysql с таблицей "пользователи" и столбцом "пароль" И класс модели ActiveRecord, называемый "пользователь", который подключен к разработке

Создайте класс модели ActiveRecord в своем приложении приложение/модели/old_user.rb

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

затем создайте задачу грабли: Приложение/Library/задачи/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

Измените при необходимости (убедитесь, что вы сохраняете атрибуты пользовательских приложений)

Тогда $ rake migrate_users