Ruby on rails 设计哈希密码和旧密码样式

Ruby on rails 设计哈希密码和旧密码样式,ruby-on-rails,devise,Ruby On Rails,Devise,我有一个带有电子邮件的用户模型(在本例中是一个注册号)和一个带有700条记录的加密密码,它是由designe生成的 看起来是这样 Number encrypted_pasword 345 76576545672 我使用此解决方案将此密码以字符串格式转换为BCrypt valid has,但出现了此错误 Started POST "/users/sign_in" for ::1 at 2017-03-01 16:23:47 -0300 Processing by Devise:

我有一个带有电子邮件的用户模型(在本例中是一个注册号)和一个带有700条记录的加密密码,它是由designe生成的

看起来是这样

Number    encrypted_pasword
345       76576545672
我使用此解决方案将此密码以字符串格式转换为BCrypt valid has,但出现了此错误

Started POST "/users/sign_in" for ::1 at 2017-03-01 16:23:47 -0300
Processing by Devise::SessionsController#create as HTML
  Parameters: {"utf8"=>"✓", "authenticity_token"=>"VnOD8783DV191j0CnruEdhDeF15SQjJEW6ilCeJxFRoZqaBuu6PtgRtfpyHeqE43KD6ra9c3e6BLitcltt2qng==", "user"=>{"email"=>"5262", "password"=>"[FILTERED]", "remember_me"=>"0"}, "commit"=>"Log in"}
  User Load (4.0ms)  SELECT  `users`.* FROM `users` WHERE `users`.`email` = '5262' ORDER BY `users`.`id` ASC LIMIT 1
Completed 500 Internal Server Error in 16ms (ActiveRecord: 4.0ms)



TypeError (no implicit conversion of nil into String):

app/models/user.rb:13:in `digest'
app/models/user.rb:13:in `hexdigest'
app/models/user.rb:13:in `rescue in valid_password?'
app/models/user.rb:10:in `valid_password?'
用户模型

class User < ApplicationRecord
  # Include default devise modules. Others available are:
  # :confirmable, :lockable, :timeoutable and :omniauthable
  devise :database_authenticatable, :registerable,
         :recoverable, :rememberable, :trackable, :validatable

  alias :devise_valid_password? :valid_password?

  def valid_password?(encrypted_password)
    begin
      super(encrypted_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.encrypted_password = encrypted_password
      true
    end
  end
end
但我收到了这个错误,我被重定向到登录页面

Started POST "/users/sign_in" for ::1 at 2017-03-01 17:01:10 -0300
Processing by Devise::SessionsController#create as HTML
  Parameters: {"utf8"=>"✓", "authenticity_token"=>"+Gk/T1r1k1zHiLIXFCupiTxOudwcx1lLAQOiS6W7teiU54UUAvB6AvpmZ+LfXBpyiPbq9Z20IZ8bIyZdWqCx8g==", "user"=>{"email"=>"5262", "password"=>"[FILTERED]", "remember_me"=>"0"}, "commit"=>"Log in"}
  User Load (4.0ms)  SELECT  `users`.* FROM `users` WHERE `users`.`email` = '5262' ORDER BY `users`.`id` ASC LIMIT 1

Completed 401 Unauthorized in 40ms (ActiveRecord: 4.0ms)


Processing by Devise::SessionsController#new as HTML
  Parameters: {"utf8"=>"✓", "authenticity_token"=>"+Gk/T1r1k1zHiLIXFCupiTxOudwcx1lLAQOiS6W7teiU54UUAvB6AvpmZ+LfXBpyiPbq9Z20IZ8bIyZdWqCx8g==", "user"=>{"email"=>"5262", "password"=>"[FILTERED]", "remember_me"=>"0"}, "commit"=>"Log in"}
  Rendering C:/Ruby23/lib/ruby/gems/2.3.0/gems/devise-4.2.0/app/views/devise/sessions/new.html.erb within layouts/application
  Rendered C:/Ruby23/lib/ruby/gems/2.3.0/gems/devise-4.2.0/app/views/devise/shared/_links.html.erb (8.0ms)
  Rendered C:/Ruby23/lib/ruby/gems/2.3.0/gems/devise-4.2.0/app/views/devise/sessions/new.html.erb within layouts/application (184.1ms)
  Rendered shared-templates/_header.html.erb (8.0ms)
Completed 200 OK in 1963ms (Views: 1627.1ms | ActiveRecord: 0.0ms)
试试这个:

 def valid_password?(input_password)
    begin
      super(input_password)
    rescue BCrypt::Errors::InvalidHash
      return false unless Digest::SHA1.hexdigest(input_password) == encrypted_password
      logger.info "User #{email} is using the old password hashing method, updating attribute."
      self.password= input_password
      true
    end
  end
如果使用bcrypt手动散列所有旧密码,则可以改为:

def valid_password?(password)
  begin
    super(password)
  rescue BCrypt::Errors::InvalidHash
    super(Digest::SHA1.hexdigest(password))
  end
end

您可以发布控制器操作的代码
users#sign_in
吗?或者这是由designe自动处理的吗?@eiko它由designehi生成,eiko,谢谢您的帮助。它为#提供了一个错误未定义的局部变量或方法'params',但我不知道我是使用“password”还是“encrypted_password”,因为我的模型设置为encrypted_password@VictorRodriguez我用新的代码更新了我的答案,希望它能起作用。我正在尝试使用each来获取数据库中存储的每个密码,使用BCrypt::Password对其进行散列。再次创建并保存它。这是个好主意吗?我认为这是个好主意!如果手动转换密码,则可以进行更简单的设计验证。我会更新我的答案以反映。
def valid_password?(password)
  begin
    super(password)
  rescue BCrypt::Errors::InvalidHash
    super(Digest::SHA1.hexdigest(password))
  end
end