微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

测试用户是否应该对用户密码进行哈希处理时,rspec 中的 Bcrypt 哈希无效

如何解决测试用户是否应该对用户密码进行哈希处理时,rspec 中的 Bcrypt 哈希无效

让我知道在模型或rspec中修复什么,以便测试可以成功地从数据库级别加密和解密密码

我最初尝试使用 has_secure_password 和显式 def password=(password) 方法,但在 User 模型类中,我现在有一个encrypt_passwordclear_password 的保存回调,它在数据库已更新

以下是架构、模型和 rspec 测试:

class createusers < ActiveRecord::Migration[6.1]
  def change
    create_table :users do |t|
      t.string :username
      t.string :password_digest
      t.timestamps
    end
  end
end

class User < ApplicationRecord
    include BCrypt
    
    attr_accessor :username,:password
    validates :username,:presence => true,:uniqueness => true,:length => { :in => 3..20 }
    validates :password,:confirmation => true #password_confirmation attr
    validates_length_of :password,:in => 6..20,:on => :create

    before_save :encrypt_password
    after_save :clear_password

    def encrypt_password
        if password.present?
            self.password_digest = BCrypt::Password.create(password)
        end
    end

    def clear_password
        self.password = nil
    end

end
require 'rails_helper'
include BCrypt

RSpec.describe User,type: :model do
    it "should hash a user's password" do 
        @user = User.new
        @password = Password.create("my grand secret")
        @password = "my grand secret"
        @user.password

        # store it safely
        @user.update_attribute(:password,@password)

        # read it back
        @user.reload
        @db_password = Password.new(@user.password)

        # compare it after retrieval
        expect(@db_password).to eql("my grand secret")
        expect(@db_password).to_not eql("a paltry guess")
    end
end
Failures:

  1) User should hash a user's password
     Failure/Error: @db_password = Password.new(@user.password)

     BCrypt::Errors::InvalidHash:
       invalid hash
     # ./spec/models/user_spec.rb:16:in `new'
     # ./spec/models/user_spec.rb:16:in `block (2 levels) in <top (required)>'

Finished in 0.19792 seconds (files took 0.56839 seconds to load)
1 example,1 failure

Failed examples:

rspec ./spec/models/user_spec.rb:5 # User should hash a user's password

bcrypt gem 要求的数据库字段名称password_digest

解决方法

password 属性仅用于设置或更新 password_digest

password 不存储在数据库中。因此,当您从数据库中获取用户并初始化用户实例时,password 属性将始终为空。

@user.reload
@user.password # => nil
Password.new(@user.password) # => error because password is nil 

您的测试应如下所示:

it "should hash a user's password" do
  password = "my grand secret"
  user = User.create!(password: password)
  expect(user.password_digest).to eq(BCrypt::Password.create(password))
end

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。