Пароль BCrypt не совпадает при изменении через Mutator Laravel 5.4

У меня есть проект Laravel 5.4, в котором я пытаюсь запустить простой интеграционный тест, который проверяет, может ли пользователь правильно войти в систему, для этого я создаю нового пользователя через Factory.

    $user = factory(User::class)->create(['password' =>'secret']);

Тогда в моем тесте

    $this->visitRoute('admin.login')
         ->submitForm('LOGIN', ['email' => $user->email, 'password' => 'secret'])
         ->seeIsAuthenticated()
         ->seeStatusCode(200);

Пользователь никогда не аутентифицируется, я могу подтвердить, что адрес электронной почты $user-> совпадает с адресом в БД, но пароль никогда не соответствует...

Поэтому я проверил хэш, сгенерированный в БД, с «секретной» строкой на этом веб-сайте https://www.dailycred.com/article/bcrypt-calculator

Я получаю сообщение об ошибке invalid salt revision я озадачен, что это такое? Я хеширую пароль с помощью мутатора, который выглядит так

public function setPasswordAttribute($value) {
    $this->attributes['password'] = bcrypt($value);
}

В соответствии с советом, уже данным в одном из комментариев ниже, я попробовал следующее решение.

    $hasher = new BcryptHasher();
    $hash = $hasher->make($value);

    $this->attributes['password'] = $hash;

Через xDebug я могу сказать, что он дважды вводит метод make(), один раз при инициализации до вызова мутатора, и в этот момент он отправляет случайный набор символов, затем он запускает мутатор и команду make() со строкой secret Как и ожидалось, я извлекаю сгенерированный хэш и обнаруживаю ту же проблему... invalid salt revision


person João Serra    schedule 04.04.2017    source источник
comment
Похоже, вы используете необработанную функцию bcrypt(), но вам может понадобиться создать экземпляр Illuminate\Hashing\BcryptHasher и вызвать $hasher-›make($value) для создания хэша, включающего все, что установлено в Ларавельная среда   -  person markdwhite    schedule 04.04.2017
comment
@markdwhite не сработал :(   -  person João Serra    schedule 04.04.2017
comment
Если вы вызываете его через мутатор, как вы думаете, ModelFactory вызовет это при создании? Возможно, factory(User::class)->create(['password' => $alreadyHashedPassword])   -  person markdwhite    schedule 04.04.2017
comment
@markdwhite Я проверил его на xdebug, и он действительно попал в мутатор ... я не понимаю, если я не могу использовать мутаторы в ModelFactories, это будет означать, что сами ModelFactories сломаны, какой смысл в фабриках, если я нельзя их так использовать?   -  person João Serra    schedule 04.04.2017
comment
Я понимаю вашу точку зрения, и я вижу, что мутатор будет вызван. Похоже, у вас появилось больше информации после последнего редактирования, так что я буду следить за обновлениями.   -  person markdwhite    schedule 04.04.2017
comment
@markdwhite я ошибся, причина случайной строки заключалась в том, что она дважды вызывает метод make (), один раз перед мутатором и еще раз после него. Он работает со стоимостью 10, я полагаю, что это значение по умолчанию для BCrypt в Laravel, верно?   -  person João Serra    schedule 04.04.2017
comment
Да, по умолчанию 10. Я установил низкое значение для модульных тестов в TestCase (последний комментарий здесь, чтобы избежать расширенного обсуждения)   -  person markdwhite    schedule 04.04.2017
comment
Я спрашиваю из любопытства - почему вы не используете функцию password_hash для хеширования пароля? В чем подвох этого вашего метода, чем он хорош?   -  person Mjh    schedule 04.04.2017


Ответы (2)


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

public function setPasswordAttribute($value)
{
    if( \Hash::needsRehash($value) ) {
        $value = \Hash::make($value);
    }
    $this->attributes['password'] = $value;
} 
person dparoli    schedule 04.04.2017
comment
нет, та же проблема, например, для «секрета» он сгенерировал следующий хэш $2y$10$q05LuNs5TkLEvrLvv7.bx.26cRPdw1NXooGHUPvp7xPW/1AemmlJS Простая проверка в Интернете быстро говорит мне, что этот хэш недействителен для этой строки :( - person João Serra; 04.04.2017

Я понял проблему, это было глупо, поэтому в моем LoginController я проверял, установлен ли у пользователя активный флаг вместе с адресом электронной почты и паролем...

protected function attemptLogin(Request $request)
{
    return Auth::attempt([
        'email' => $request->input('email'),
        'password' => $request->input('password'),
        'active' => 1
    ]);
}

По сути, моя фабрика имеет правило 50/50 в отношении «активного» флага, поэтому каждый раз, когда у сгенерированного пользователя был активный флаг = 1, он работал, а в остальных 50% случаев он терпел неудачу.

Извините, но спасибо за вашу помощь всем, надеюсь, это поможет кому-то в будущем :)

person João Serra    schedule 04.04.2017