Guard authenticator 不支持从XAMPP 更改为LAMPP 后的请求
Guard authenticator does not support the request after change from XAMPP to LAMPP
我有一个在 XAMPP 中开发的 symfony 4 应用程序。现在我几周前在 Unbuntu 中设置了 LAMPP。现在我第一次在文件权限为 775 的 Ubuntu 上安装我的 symfony 项目时它不起作用。在浏览器中,我收到消息 "Not Found - The requested URL was not found on this server." 我在(错误)日志中唯一能找到的是:
[2020-04-19T22:56:51.564711+02:00] request.INFO: Matched route "homepage". {"route":"homepage","route_parameters":{"_route":"homepage","path":"/login","permanent":false,"keepQueryParams":true,"_controller":"Symfony\Bundle\FrameworkBundle\Controller\RedirectController::urlRedirectAction"},"request_uri":"http://192.168.0.100:8082/","method":"GET"} []
[2020-04-19T22:56:51.569203+02:00] security.DEBUG: Checking for guard authentication credentials. {"firewall_key":"main","authenticators":1} []
[2020-04-19T22:56:51.569331+02:00] security.DEBUG: Checking support on guard authenticator. {"firewall_key":"main","authenticator":"App\Security\LoginFormAuthenticator"} []
[2020-04-19T22:56:51.569400+02:00] security.DEBUG: Guard authenticator does not support the request. {"firewall_key":"main","authenticator":"App\Security\LoginFormAuthenticator"} []
而且我不知道为什么它不起作用。你能帮帮我吗?
这是 Guard 验证码:
<?php
namespace App\Security;
use App\Entity\User;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\Security\Core\Exception\CustomUserMessageAuthenticationException;
use Symfony\Component\Security\Core\Exception\InvalidCsrfTokenException;
use Symfony\Component\Security\Core\Encoder\UserPasswordEncoderInterface;
use Symfony\Component\Security\Core\Security;
use Symfony\Component\Security\Core\User\UserInterface;
use Symfony\Component\Security\Core\User\UserProviderInterface;
use Symfony\Component\Security\Csrf\CsrfToken;
use Symfony\Component\Security\Csrf\CsrfTokenManagerInterface;
use Symfony\Component\Security\Guard\Authenticator\AbstractFormLoginAuthenticator;
use Symfony\Component\Security\Http\Util\TargetPathTrait;
use Symfony\Contracts\Translation\TranslatorInterface;
/**
* Authenticator for login form
*
*/
class LoginFormAuthenticator extends AbstractFormLoginAuthenticator
{
use TargetPathTrait;
private $entityManager;
private $urlGenerator;
private $csrfTokenManager;
private $passwordEncoder;
private $translator;
/**
* LoginFormAuthenticator constructor
*
* @param EntityManagerInterface $entityManager entity manager
* @param UrlGeneratorInterface $urlGenerator url generator
* @param CsrfTokenManagerInterface $csrfTokenManager csrf token manager
* @param UserPasswordEncoderInterface $passwordEncoder password encoder
* @param TranslatorInterface $translator translator
*/
public function __construct(EntityManagerInterface $entityManager, UrlGeneratorInterface $urlGenerator, CsrfTokenManagerInterface $csrfTokenManager, UserPasswordEncoderInterface $passwordEncoder, TranslatorInterface $translator)
{
$this->entityManager = $entityManager;
$this->urlGenerator = $urlGenerator;
$this->csrfTokenManager = $csrfTokenManager;
$this->passwordEncoder = $passwordEncoder;
$this->translator = $translator;
}
/**
* Called on every request to decide if this authenticator should be
* used for the request.
*
* @param Request $request request
*
* @return boolean Returning false will cause this authenticator to be skipped.
*/
public function supports(Request $request)
{
return 'login' === $request->attributes->get('_route') && $request->isMethod('POST');
}
/**
* Get credentials
*
* @param Request $request request
*
* @return Array Returns with credentials array
*/
public function getCredentials(Request $request)
{
$credentials = [
'email' => $request->request->get('login')["email"],
'password' => $request->request->get('login')["password"],
'csrf_token' => $request->request->get('login')["_token"],
];
$request->getSession()->set(
Security::LAST_USERNAME,
$credentials['email']
);
return $credentials;
}
/**
* Get user
*
* @param Array $credentials credentials
* @param UserInterface $user user
*
* @return boolean returns true if password is valid. Otherwise false.
*/
public function getUser($credentials, UserProviderInterface $userProvider)
{
$token = new CsrfToken('authenticate', $credentials['csrf_token']);
if (!$this->csrfTokenManager->isTokenValid($token)) {
//throw new CustomUserMessageAuthenticationException($this->translator->trans('security.login.csrf', [], 'security'));
throw new InvalidCsrfTokenException();
}
$user = $this->entityManager->getRepository(User::class)->findUser($credentials['email']);
if (!$user) {
// fail authentication with a custom error
throw new CustomUserMessageAuthenticationException($this->translator->trans('general.error.emailOrUsername.not.found', [], 'messages'));
}
else {
if(!$user->getActive()) {
throw new CustomUserMessageAuthenticationException($this->translator->trans('general.error.emailOrUsername.not.active', [], 'messages'));
}
elseif(!$user->getAccepted()) {
throw new CustomUserMessageAuthenticationException($this->translator->trans('general.error.emailOrUsername.not.accepted.terms', [], 'messages'));
}
}
return $user;
}
/**
* Check credentials
*
* @param Array $credentials credentials
* @param UserInterface $user user
*
* @return boolean returns true if password is valid. Otherwise false.
*/
public function checkCredentials($credentials, UserInterface $user)
{
return $this->passwordEncoder->isPasswordValid($user, $credentials['password']);
}
/**
* Override to change what happens after a correct username/password is submitted.
*
* @param Request $request request
* @param TokenInterface $token token
* @param String $providerKey provider key
*
* @return RedirectResponse
*/
public function onAuthenticationSuccess(Request $request, TokenInterface $token, $providerKey)
{
if(!in_array($request->attributes->get('_route'), ['register'])) {
$user = $token->getUser();
$user->setLastLogin(new \DateTime());
$this->entityManager->persist($token->getUser());
$this->entityManager->flush();
}
if ($targetPath = $this->getTargetPath($request->getSession(), $providerKey)) {
return new RedirectResponse($targetPath);
}
return new RedirectResponse($this->urlGenerator->generate('admin_dashboard'));
}
/**
* get login url
*
* @return string returns url
*/
protected function getLoginUrl()
{
return $this->urlGenerator->generate('login');
}
}
我发现了我的问题。在 Xampp 中,我的 symfony 项目在 /public 目录中没有 .htaccess 的情况下工作。在 LAMPP 中,我需要 /public 目录中的 .htaccess。
因此我在我的 symfony 项目中安装了 composer require symfony/apache-pack
,并在安装过程中单击 y(es)。现在可以了。
我有一个在 XAMPP 中开发的 symfony 4 应用程序。现在我几周前在 Unbuntu 中设置了 LAMPP。现在我第一次在文件权限为 775 的 Ubuntu 上安装我的 symfony 项目时它不起作用。在浏览器中,我收到消息 "Not Found - The requested URL was not found on this server." 我在(错误)日志中唯一能找到的是:
[2020-04-19T22:56:51.564711+02:00] request.INFO: Matched route "homepage". {"route":"homepage","route_parameters":{"_route":"homepage","path":"/login","permanent":false,"keepQueryParams":true,"_controller":"Symfony\Bundle\FrameworkBundle\Controller\RedirectController::urlRedirectAction"},"request_uri":"http://192.168.0.100:8082/","method":"GET"} []
[2020-04-19T22:56:51.569203+02:00] security.DEBUG: Checking for guard authentication credentials. {"firewall_key":"main","authenticators":1} []
[2020-04-19T22:56:51.569331+02:00] security.DEBUG: Checking support on guard authenticator. {"firewall_key":"main","authenticator":"App\Security\LoginFormAuthenticator"} []
[2020-04-19T22:56:51.569400+02:00] security.DEBUG: Guard authenticator does not support the request. {"firewall_key":"main","authenticator":"App\Security\LoginFormAuthenticator"} []
而且我不知道为什么它不起作用。你能帮帮我吗?
这是 Guard 验证码:
<?php
namespace App\Security;
use App\Entity\User;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\Security\Core\Exception\CustomUserMessageAuthenticationException;
use Symfony\Component\Security\Core\Exception\InvalidCsrfTokenException;
use Symfony\Component\Security\Core\Encoder\UserPasswordEncoderInterface;
use Symfony\Component\Security\Core\Security;
use Symfony\Component\Security\Core\User\UserInterface;
use Symfony\Component\Security\Core\User\UserProviderInterface;
use Symfony\Component\Security\Csrf\CsrfToken;
use Symfony\Component\Security\Csrf\CsrfTokenManagerInterface;
use Symfony\Component\Security\Guard\Authenticator\AbstractFormLoginAuthenticator;
use Symfony\Component\Security\Http\Util\TargetPathTrait;
use Symfony\Contracts\Translation\TranslatorInterface;
/**
* Authenticator for login form
*
*/
class LoginFormAuthenticator extends AbstractFormLoginAuthenticator
{
use TargetPathTrait;
private $entityManager;
private $urlGenerator;
private $csrfTokenManager;
private $passwordEncoder;
private $translator;
/**
* LoginFormAuthenticator constructor
*
* @param EntityManagerInterface $entityManager entity manager
* @param UrlGeneratorInterface $urlGenerator url generator
* @param CsrfTokenManagerInterface $csrfTokenManager csrf token manager
* @param UserPasswordEncoderInterface $passwordEncoder password encoder
* @param TranslatorInterface $translator translator
*/
public function __construct(EntityManagerInterface $entityManager, UrlGeneratorInterface $urlGenerator, CsrfTokenManagerInterface $csrfTokenManager, UserPasswordEncoderInterface $passwordEncoder, TranslatorInterface $translator)
{
$this->entityManager = $entityManager;
$this->urlGenerator = $urlGenerator;
$this->csrfTokenManager = $csrfTokenManager;
$this->passwordEncoder = $passwordEncoder;
$this->translator = $translator;
}
/**
* Called on every request to decide if this authenticator should be
* used for the request.
*
* @param Request $request request
*
* @return boolean Returning false will cause this authenticator to be skipped.
*/
public function supports(Request $request)
{
return 'login' === $request->attributes->get('_route') && $request->isMethod('POST');
}
/**
* Get credentials
*
* @param Request $request request
*
* @return Array Returns with credentials array
*/
public function getCredentials(Request $request)
{
$credentials = [
'email' => $request->request->get('login')["email"],
'password' => $request->request->get('login')["password"],
'csrf_token' => $request->request->get('login')["_token"],
];
$request->getSession()->set(
Security::LAST_USERNAME,
$credentials['email']
);
return $credentials;
}
/**
* Get user
*
* @param Array $credentials credentials
* @param UserInterface $user user
*
* @return boolean returns true if password is valid. Otherwise false.
*/
public function getUser($credentials, UserProviderInterface $userProvider)
{
$token = new CsrfToken('authenticate', $credentials['csrf_token']);
if (!$this->csrfTokenManager->isTokenValid($token)) {
//throw new CustomUserMessageAuthenticationException($this->translator->trans('security.login.csrf', [], 'security'));
throw new InvalidCsrfTokenException();
}
$user = $this->entityManager->getRepository(User::class)->findUser($credentials['email']);
if (!$user) {
// fail authentication with a custom error
throw new CustomUserMessageAuthenticationException($this->translator->trans('general.error.emailOrUsername.not.found', [], 'messages'));
}
else {
if(!$user->getActive()) {
throw new CustomUserMessageAuthenticationException($this->translator->trans('general.error.emailOrUsername.not.active', [], 'messages'));
}
elseif(!$user->getAccepted()) {
throw new CustomUserMessageAuthenticationException($this->translator->trans('general.error.emailOrUsername.not.accepted.terms', [], 'messages'));
}
}
return $user;
}
/**
* Check credentials
*
* @param Array $credentials credentials
* @param UserInterface $user user
*
* @return boolean returns true if password is valid. Otherwise false.
*/
public function checkCredentials($credentials, UserInterface $user)
{
return $this->passwordEncoder->isPasswordValid($user, $credentials['password']);
}
/**
* Override to change what happens after a correct username/password is submitted.
*
* @param Request $request request
* @param TokenInterface $token token
* @param String $providerKey provider key
*
* @return RedirectResponse
*/
public function onAuthenticationSuccess(Request $request, TokenInterface $token, $providerKey)
{
if(!in_array($request->attributes->get('_route'), ['register'])) {
$user = $token->getUser();
$user->setLastLogin(new \DateTime());
$this->entityManager->persist($token->getUser());
$this->entityManager->flush();
}
if ($targetPath = $this->getTargetPath($request->getSession(), $providerKey)) {
return new RedirectResponse($targetPath);
}
return new RedirectResponse($this->urlGenerator->generate('admin_dashboard'));
}
/**
* get login url
*
* @return string returns url
*/
protected function getLoginUrl()
{
return $this->urlGenerator->generate('login');
}
}
我发现了我的问题。在 Xampp 中,我的 symfony 项目在 /public 目录中没有 .htaccess 的情况下工作。在 LAMPP 中,我需要 /public 目录中的 .htaccess。
因此我在我的 symfony 项目中安装了 composer require symfony/apache-pack
,并在安装过程中单击 y(es)。现在可以了。