Минитест Rails BCrypt::Errors::InvalidHash:

Я следил за учебником Hartl по Rails и внедряю мини-тесты в свой логин. В настоящее время все работает нормально, и пользователь может успешно войти в систему.

Но когда я запускаю тест своей интеграции входа, я продолжаю получать эту ошибку, когда пытаюсь переварить токен....

BCrypt::Errors::InvalidHash: invalid hash
  app/controllers/sessions_controller.rb:13:in `create'
  test/integration/users_login_test.rb:21:in `block in <class:UsersLoginTest>'
  app/controllers/sessions_controller.rb:13:in `create'
  test/integration/users_login_test.rb:21:in `block in <class:UsersLoginTest>'

Может кто-нибудь помочь мне понять эту ошибку и как я могу ее исправить, пожалуйста.

Модель

class User < ActiveRecord::Base
  belongs_to :district
  belongs_to :school

  ###Why doesn't this work?------
  def User.digest(token)
    Digest::SHA1.hexdigest(token.to_s)
  end

end

Фикстуры (users.yml)

tom:
  district_id: 1
  school_id: 6
  firstName: Tommy
  lastName: Pickles
  username: pickleman
  email: [email protected]

  ###Error on this line------
  password_digest: <%= User.digest('password') %>

Интеграция(user_login_test.rb)

require 'test_helper'

class UsersLoginTest < ActionDispatch::IntegrationTest

  def setup
    @user = users(:tom)
  end

  test "login with valid information" do
    get login_path

    ###Error on Sign Up Here------
    post sessions_path, session: { username: @user.username, password: 'password' }

    assert_redirected_to district_district_resources_path(@user.district)
    follow_redirect!
    assert_template 'sessions/new'
    assert_select "a[href=?]", login_path, count: 0
  end

end

Контроллер

class SessionsController < ApplicationController

  #create session for login
  def create
    user = User.find_by(username: params[:session][:username]) if defined? params[:session][:username]  
    district = user.district if user
    school = user.school if user

    if user && user.authenticate(params[:session][:password]) && district
        user_sign_in user
        redirect_to district_district_resources_path(district)
    else
        flash.now[:error] = 'Invalid username / password combination' # Not quite right!
        render 'new'
    end

end

person Serge Pedroza    schedule 03.11.2015    source источник


Ответы (3)


BCrypt::Errors::InvalidHash вызывается, когда хэш, хранящийся в password_digest, не является допустимым хэшем BCrypt.

Короче говоря, вы не можете просто сбросить туда любой SHA1, вам нужно создать такой хэш:

sha1_password = Digest::SHA1.hexdigest(token.to_s)
BCrypt::Password.create(sha1_password).to_s

См. этот ответ для более подробного объяснения этой темы.

person awendt    schedule 03.11.2015
comment
Когда я это делаю, весь мой логин перестает работать, пользователь перенаправляется, как будто пользователь не вошел в систему. - person Serge Pedroza; 03.11.2015

Нашел обходной путь.

Создал пользователя с паролем: пароль

Затем я напрямую добавил сгенерированный password_digest в файл users.yml для работы минитеста.

пользователи.yml

tom:
  district_id: 1
  school_id: 6
  firstName: Tommy
  lastName: Pickles
  username: pickleman
  email: [email protected]

  ###HERE----
  password_digest: $2a$10$g/A4D6KtaLtxvm2lZ8C.vuPvl8Zu2TrbnPYpM6r59Wu397hlY42GO
person Serge Pedroza    schedule 03.11.2015

Если вы пытаетесь сгенерировать пароль для теста minitest с помощью приспособлений, я предлагаю вам взглянуть на это: Функциональное тестирование с помощью Rails и Devise. Что поставить в мои светильники?

person ReggieB    schedule 03.11.2015