设计哈希密码和旧密码样式

时间:2017-03-01 19:33:26

标签: ruby-on-rails devise

我有一个带有电子邮件的用户模型(在这种情况下是一个注册号)和一个有700条记录的encrypted_pa​​ssword,它由设计生成。

看起来像

Number    encrypted_pasword
345       76576545672

我使用此解决方案将此密码以字符串格式转换为BCrypt有效,但我收到此错误

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

让这个问题成为我解决问题的最后一次尝试。 谢谢你的帮助!

修改

我用过这个:

return false unless Digest::SHA1.hexdigest(:password.to_s) == encrypted_password

但我收到了这个错误,我被重定向到登录页面

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)

1 个答案:

答案 0 :(得分:1)

试试这个:

 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