首次登录 symfony 应用程序时强制更改密码
Posted
技术标签:
【中文标题】首次登录 symfony 应用程序时强制更改密码【英文标题】:Force password change on first login in symfony app 【发布时间】:2020-06-09 17:38:54 【问题描述】:我正在尝试实现一种方法来强制用户在第一次登录我的 Symfony 应用程序时更改他们的默认密码。
目前我已经设置了一个事件监听器来监听InteractiveLogin
事件。
namespace App\EventListener;
use App\Entity\User;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
use Symfony\Component\Security\Http\Event\InteractiveLoginEvent;
class LoginListener
private $urlGenerator;
public function __construct(UrlGeneratorInterface $urlGenerator)
$this->urlGenerator = $urlGenerator;
public function onSecurityInteractiveLogin(InteractiveLoginEvent $event)
// Get the User entity.
$user = $event->getAuthenticationToken()->getUser();
if ($user->getForcepasswordchange())
return new RedirectResponse($this->urlGenerator->generate('force_password_change'));
它基本上检查用户实体中的布尔标志,该标志为新用户设置为真。它获取用户并且该方法到达RedirectResponse
行,但最终只是转到主页(默认登录行为)。
我不确定如何强制它不继续登录过程并重定向到我的密码更改页面。
【问题讨论】:
您可以进行登录计数。如果登录计数 = 1,则强制更改密码。您还可以合并自登录以来的日期,并强制用户在…… 3 个月后更改密码,以增强密码安全性。 嗨,我的标志都在用户实体中工作,我只是无法让事件监听器重定向到密码更改页面,它只是转到主页。如果我的标志为真,我认为我需要以某种方式中断身份验证过程,以便身份验证不会进入主页。 【参考方案1】:您不能通过收听InteractiveLoginEvent
来执行此操作。
这个event 不包括对响应对象的访问,并且返回一个来自监听器的对象不会让你无处可去,因为没有人在等待监听器返回任何东西。 p>
但您可以在 RequestEvent
侦听器/订阅者上执行此操作:
class PasswordChangeSubscriber implements EventSubscriberInterface
private Security $security;
private UrlGeneratorInterface $urlGenerator;
public function __construct(Security $security, UrlGeneratorInterface $urlGenerator)
$this->security = $security;
$this->urlGenerator = $urlGenerator;
public static function getSubscribedEvents(): array
return [
KernelEvents::REQUEST => [['forcePasswordChange', 0]],
];
public function forcePasswordChange(RequestEvent $event): void
// only deal with the main request, disregard subrequests
if (!$event->isMasterRequest())
return;
// if we are visiting the password change route, no need to redirect
// otherwise we'd create an infinite redirection loop
if ($event->getRequest()->get('_route') === 'force_password_change')
return;
$user = $this->security->getUser();
// if you do not have a valid user, it means it's not an authenticated request, so it's not our concern
if (!$user instanceof YourUserClass)
return;
// if it's not their first login, and they do not need to change their password, move on
if (!$user->isPasswordChangeRequired())
return;
// if we get here, it means we need to redirect them to the password change view.
$event->setResponse(new RedirectResponse($this->urlGenerator->generate('force_password_change')));
【讨论】:
您好,感谢您的帮助。我走得更远,但现在我在重定向发生时遇到“ERR_TOO_MANY_REDIRECTS”。不知道为什么,即使我只是重定向回登录页面? 是的,你得到了一个无限的重定向循环。我的错。我现在在手机上,当我回到家时,我会更新答案。但是你需要做的是检查用户没有尝试访问“更改密码”页面,并且不要在这种情况下执行重定向。 酷,我会尝试解决,但如果我自己无法解决,我可能需要您稍后更新解决方案。再次感谢,非常有帮助 我比我更喜欢你的方法,它看起来更整洁。再次感谢!【参考方案2】:这是基于上述答案和帮助的最后一段代码
<?php
namespace App\EventSubscriber;
use App\Entity\User;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpKernel\KernelEvents;
use Symfony\Component\HttpKernel\Event\RequestEvent;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
use Symfony\Component\Security\Core\Security;
class PasswordChangeSubscriber implements EventSubscriberInterface
private $security;
private $urlGenerator;
public function __construct(Security $security, UrlGeneratorInterface $urlGenerator)
$this->security = $security;
$this->urlGenerator = $urlGenerator;
public static function getSubscribedEvents(): array
return [
KernelEvents::REQUEST => [
['forcePasswordChange', 0]
],
];
public function forcePasswordChange(RequestEvent $event): void
// only deal with the main request, disregard subrequests
if (!$event->isMasterRequest())
return;
$user = $this->security->getUser();
// if you do not have a valid user, it means it's not an authenticated request, so it's not our concern
if (!$user instanceof User)
return;
// if it's not their first login, and they do not need to change their password, move on
if (!$user->getForcepasswordchange())
return;
// if we get here, it means we need to redirect them to the password change view.
$redirectTo = $this->urlGenerator->generate('changepassword', ['username' => $user->getUsername()]);
if ($event->getRequest()->getRequestUri() != $redirectTo)
$event->setResponse(new RedirectResponse($redirectTo));
return;
【讨论】:
以上是关于首次登录 symfony 应用程序时强制更改密码的主要内容,如果未能解决你的问题,请参考以下文章
在 ASP.NET Core 中首次登录时强制重定向到另一个页面
新用户首次登录时强制进行 2 因素身份验证 .NET Core
EasyNVR新增功能:播放器加载图标可配置匿名登录配置首次登录密码强制修改
Facebook 应用程序 - 用户首次登录应用程序后测试用户 ID 更改