Преобразование существующего хэша пароля в Devise - PullRequest
13 голосов
/ 24 мая 2011

Я пытаюсь преобразовать существующую модель администратора в Devise.У нас уже есть хэш пароля, но он явно не совместим с Devise.Что я хотел бы сделать, это принять форму входа и проверить предоставленный пароль с зашифрованным паролем.Если это неверно, используйте старый хеш, чтобы проверить пароль, и, если он совпадает, очистите старое поле password_hash и установите пароль Devise для предоставленного пароля и сохраните модель.

Каков наилучший способ продвижения вперед?Я подозреваю, что мне нужно что-то переопределить, возможно, в пользовательском контроллере, но я не совсем уверен, как действовать.

Ответы [ 5 ]

28 голосов
/ 31 января 2012

Вы можете позволить Devise выполнять «тяжелую работу» по шифрованию пароля с помощью новой схемы шифрования, как показано в https://gist.github.com/1704632:

class User < ActiveRecord::Base
  alias :devise_valid_password? :valid_password?

  def valid_password?(password)
    begin
      super(password)
    rescue BCrypt::Errors::InvalidHash
      return false unless Digest::SHA1.hexdigest(password) == encrypted_password
      logger.info "User #{email} is using the old password hashing method, updating attribute."
      self.password = password
      true
    end
  end
end
3 голосов
/ 20 сентября 2012

Сначала вам нужно скопировать password_salt и encrypted_password в вашу новую объектную модель

Используя это, потому что я должен экспортировать пользователя базы данных в другое приложение и старый, приложение использует devise 1.0.x, а новое приложение использует 2.1.x

Class User < ActiveRecord::Base
 alias :devise_valid_password? :valid_password?
    def valid_password?(password)
      begin
        devise_valid_password?(password)
      rescue BCrypt::Errors::InvalidHash
        salt = password_salt
        digest = nil
        10.times { digest = ::Digest::SHA1.hexdigest('--' << [salt, digest, password, nil].flatten.join('--') << '--') }
        digest
        return false unless digest == encrypted_password
        logger.info "User #{email} is using the old password hashing method, updating attribute."
        self.password = password
        self.password_salt = nil # With this you will knew what object already using the new authentication by devise
        self.save
        true
      end
    end
end
3 голосов
/ 01 сентября 2011

Используя шифровщик bcrypt в Devise, я закончил тем, что делал со своими прежними данными:

В моделях / user.rb

# Because we have some old legacy users in the database, we need to override Devises method for checking if a password is valid.
# We first ask Devise if the password is valid, and if it throws an InvalidHash exception, we know that we're dealing with a
# legacy user, so we check the password against the SHA1 algorithm that was used to hash the password in the old database.
alias :devise_valid_password? :valid_password?
def valid_password?(password)
  begin
    devise_valid_password?(password)
  rescue BCrypt::Errors::InvalidHash
    Digest::SHA1.hexdigest(password) == encrypted_password
  end
end

Как вы можете видеть, devise генерирует исключение InvalidHash при обнаружении недопустимого хеша, что происходит при аутентификации унаследованного пользователя. Я использую это для возврата к алгоритму хеширования, используемому для создания оригинального старого хэша.

Хотя пароль не изменяется, но его можно просто добавить к методу, если это необходимо.

2 голосов
/ 25 июля 2013

Если вы переходите от SHA512, решение немного сложнее, чем решение moeffju SHA1 :

def valid_password?(password)
  if has_legacy_password?
    return false unless valid_legacy_password?(password)
    convert_legacy_password!(password)
    true
  else
    super(password)
  end
end

protected

def has_legacy_password?
  password_salt.present?
end

def convert_legacy_password!(password)
  self.password = password
  self.password_salt = nil
  self.save
end

def valid_legacy_password?(password)
  stretches = 10
  salt = password_salt
  pepper = nil
  digest = pepper

  stretches.times do
    tokens = [salt, digest, password, pepper]
    digest = Digest::SHA512.hexdigest('--' << tokens.flatten.join('--') << '--')
  end

  Devise.secure_compare(encrypted_password, digest)
end

Обязательно замените stretches и pepperзначения, которые вы использовали для шифрования паролей.

0 голосов
/ 08 января 2012

следуйте инструкциям Томаса Диппеля. Я сделал суть, обновляющую пароль: https://gist.github.com/1578362

    # Because we have some old legacy users in the database, we need to override Devises method for checking if a password is valid.
# We first ask Devise if the password is valid, and if it throws an InvalidHash exception, we know that we're dealing with a
# legacy user, so we check the password against the SHA1 algorithm that was used to hash the password in the old database.
#SOURCES OF SOLUTION:
# /4668615/preobrazovanie-suschestvuyschego-hesha-parolya-v-devise
# https://github.com/binarylogic/authlogic/blob/master/lib/authlogic/crypto_providers/sha512.rb
# https://github.com/plataformatec/devise/blob/master/lib/devise/encryptors/authlogic_sha512.rb

alias :devise_valid_password? :valid_password?
def valid_password?(password)
  debugger
  begin
    devise_valid_password?(password)
  rescue BCrypt::Errors::InvalidHash
    stretches = 20
    digest = [password, self.password_salt].flatten.join('')
    stretches.times {digest = Digest::SHA512.hexdigest(digest)}
    if digest == self.encrypted_password
      #Here update old Authlogic SHA512 Password with new Devise ByCrypt password
      # SOURCE: https://github.com/plataformatec/devise/blob/master/lib/devise/models/database_authenticatable.rb
      # Digests the password using bcrypt.
      # Default strategy for Devise is BCrypt
      # def password_digest(password)
      # ::BCrypt::Password.create("#{password}#{self.class.pepper}", :cost => self.class.stretches).to_s
      # end
      self.encrypted_password = self.password_digest(password)
      self.save
      return true
    else
      # If not BCryt password and not old Authlogic SHA512 password Dosn't my user
      return false
    end
  end
end 
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...