Реализация двухшагового восстановления пароля с подтверждением операции по электронной почте. Защита от спама и возможной перегрузки сервера.
Скрытый контент
Чтобы не пропускать новые эпизоды подпишитесь на наш канал @deworkerpro в Telegram
Комментарии (11)
Arunas
Спасибо. Об ролях пользователей: будет про групах пользователей, их permision?
Дмитрий Елисеев
Будет про привязку разрешений к ролям.
Arunas
Спс
Bondarenko Alexandr
Кстати, службу для хэширования пароля еще хорошо бы передавать в метод resetPassword, чтобы не дублировать проверку предусловий по хэндлерам: к примеру, бывают предусловия, когда пароль пользователя ограничен каким-то количеством символов, а также должны присутствовать цифры и латиница.
Но код станет немного сложнее, т.к. у User'a появится зависимость. В unit тестах придется ее мокать, и в UserBuilder инжектить PasswordHasher.
Дмитрий Елисеев
Да. Ещё хэшер удобно передавать в метод changePassword для проверки текущего пароля:
class User
{
...
public function changePassword(string $current, string $new, PasswordHasher $hasher): void
{
if (!$hasher->validate($current, $this->passwordHash)) {
throw new DomainException('Invalid current password.');
}
$this->passwordHash = $hasher->hash($new);
}
}
А если есть условия, то можно при желании обернуть в объект-значение Password.
Bondarenko Alexandr
Дмитрий, спасибо за материал!
Есть такой вопрос: как вы убеждаетесь, что код для прикладных хэндлеров реализован верно? Тесты для них в проекте отсутствуют.
Дмитрий Елисеев
Их будем тестировать сквозными функциональными тестами контроллеров.
Олег
Дмитрий, возник такой вопрос.
Почему для генерации токенов в тестах мы не используем токенайзер?
Просто уже второй тест, где мы делаем приватный метод возвращающий токен, при том, что есть целый объект, который эти токены штампует.
Дмитрий Елисеев
Чтобы минимизировать использование в тестах других классов. Так как Tokenizer со временем можем дорабатывать и придётся тоже исправлять все тесты.
А чтобы не копипастить приватный метод, можно вынести его в статический метод отдельного класса и вызывать вроде $token = Test\Tokenizer::generate($expires).
Олег
Дмитрий, возник вот так вопрос (возможно он решается дальше по курсу).
Модуль Auth является, как я понимаю, отдельной доменной зоной, со своими сущностями и так далее. Контроллер ничего не трогает, а лишь обращается к командам. Но тут у нас появляется еще одна доменная зона, аукцион (или еще что). И в командах аукциона нам надо знать о пользователе. Пользователь у нас в доменной зоне Auth. Как мы будет к нему обращаться и работать с ним? Или мы будем использовать Entity из соседнего модуля? Не очень ясно. Плюс если так, то появляется зависимость одного модуля от другого. Какие тут решения?
Заранее спасибо за ответ
Дмитрий Елисеев
В модуле аукциона мы создадим отдельную сущность участника с тем же id и там будем работать уже с ней.
Спасибо. Об ролях пользователей: будет про групах пользователей, их permision?
Будет про привязку разрешений к ролям.
Спс
Кстати, службу для хэширования пароля еще хорошо бы передавать в метод resetPassword, чтобы не дублировать проверку предусловий по хэндлерам: к примеру, бывают предусловия, когда пароль пользователя ограничен каким-то количеством символов, а также должны присутствовать цифры и латиница. Но код станет немного сложнее, т.к. у User'a появится зависимость. В unit тестах придется ее мокать, и в UserBuilder инжектить PasswordHasher.
Да. Ещё хэшер удобно передавать в метод changePassword для проверки текущего пароля:
А если есть условия, то можно при желании обернуть в объект-значение
Password
.Дмитрий, спасибо за материал! Есть такой вопрос: как вы убеждаетесь, что код для прикладных хэндлеров реализован верно? Тесты для них в проекте отсутствуют.
Их будем тестировать сквозными функциональными тестами контроллеров.
Дмитрий, возник такой вопрос.
Почему для генерации токенов в тестах мы не используем токенайзер?
Просто уже второй тест, где мы делаем приватный метод возвращающий токен, при том, что есть целый объект, который эти токены штампует.
Чтобы минимизировать использование в тестах других классов. Так как Tokenizer со временем можем дорабатывать и придётся тоже исправлять все тесты.
А чтобы не копипастить приватный метод, можно вынести его в статический метод отдельного класса и вызывать вроде
$token = Test\Tokenizer::generate($expires)
.Дмитрий, возник вот так вопрос (возможно он решается дальше по курсу). Модуль Auth является, как я понимаю, отдельной доменной зоной, со своими сущностями и так далее. Контроллер ничего не трогает, а лишь обращается к командам. Но тут у нас появляется еще одна доменная зона, аукцион (или еще что). И в командах аукциона нам надо знать о пользователе. Пользователь у нас в доменной зоне Auth. Как мы будет к нему обращаться и работать с ним? Или мы будем использовать Entity из соседнего модуля? Не очень ясно. Плюс если так, то появляется зависимость одного модуля от другого. Какие тут решения? Заранее спасибо за ответ
В модуле аукциона мы создадим отдельную сущность участника с тем же id и там будем работать уже с ней.
Или войти через: