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





Звучит как классический Double-Opt-In, и он должен работать только в том случае, если пользователь нажал на ссылку подтверждения, так как это завершает весь процесс регистрации.
Рассмотрим следующие шаги:
GuardAuthenticator подходAbstractAuthenticator подход (symfony 5.1+)Таким образом, успешная регистрация создает Пользователя, но не активирует его. Поэтому вам нужно каким-то образом пометить свои пользовательские объекты как включенные/активированные.
Что-то вроде
/**
*
* @var bool
*
* @ORM\Column(type = "boolean", name = "is_enabled", options = {"default": false})
*/
protected $isEnabled = false;
Поскольку по умолчанию установлено значение FALSE, вам не нужно настраивать логику регистрации. (За исключением автоматического входа в систему после регистрации, вам нужно будет удалить эту часть)
Теперь вам нужно изменить логику входа и проверить, включен/активирован ли пользователь, который пытается войти.
GuardAuthenticator подходЕсли ваш логин основан на AbstractGuardAuthenticator (вероятно, AbstractFormLoginAuthenticator), вам нужно настроить методы getUser() (или getCredentials()). Все зависит от того, как вы хотите общаться с пользователем.
Пример с getUser()
public function getUser($credentials, UserProviderInterface $userProvider): ?UserInterface
{
$username = $credentials['_username'];
$foundUser = $this->usersRepo->findOneByUsername($username);
if (!$foundUser->isEnabled()) {
throw new CustomUserMessageAccountStatusException('Your account was not enabled/activated yet.');
}
if ($foundUser instanceof UserInterface) {
return $foundUser;
}
return null;
}
Специальные CustomUserMessageAuthenticationException (или CustomUserMessageAccountStatusException) от Symfony\Component\Security\Core\Exception творят чудеса. Вот аналогичный пример
AbstractAuthenticator подход (symfony 5 и symfonyn 6)Работает на:
enable_authenticator_manager: true в security.yamlЕсли вы используете более новую систему аутентификации Symfony, вам придется делать аналогичные вещи в вашем методе authenticate.
public function authenticate(){
return new Passport(
new UserBadge($email, function($userIdentifier) {
// optionally pass a callback to load the User manually
$foundUser = $this->usersRepo->findOneBy(['email' => $userIdentifier]);
if (!$foundUser) {
throw new UserNotFoundException();
}
if (!$foundUser->isEnabled()) {
throw new CustomUserMessageAccountStatusException('Your account was not enabled/activated yet.');
}
return $foundUser;
}),
);
}
И снова CustomUserMessageAccountStatusException/CustomUserMessageAuthenticationException творим чудеса.
Теперь вам нужно активировать/включить пользователя после того, как он нажал на ссылку в электронном письме. Это должно быть довольно просто, поэтому здесь нет ничего исключительного. Просто добавь
$user->setIsEnabled(true);
$entityManager->flush();
в вашем действии подтверждения, и этого должно быть достаточно.