我正在Symfony 4中创建一个简单的登录身份验证系统,并使用安全组件Guard。我的FormLoginAuthenticator如下:
<?php
namespace App\Security;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\Routing\RouterInterface;
use Symfony\Component\Security\Core\Encoder\UserPasswordEncoderInterface;
use Symfony\Component\Security\Core\Exception\BadCredentialsException;
use Symfony\Component\Security\Core\Exception\AuthenticationException;
use Symfony\Component\Security\Core\User\UserInterface;
use Symfony\Component\Security\Core\User\UserProviderInterface;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\Security\Guard\Authenticator\AbstractFormLoginAuthenticator;
use Symfony\Component\Security\Core\Security;
class FormLoginAuthenticator extends AbstractFormLoginAuthenticator
{
private $router;
private $encoder;
public function __construct(RouterInterface $router, UserPasswordEncoderInterface $encoder)
{
$this->router = $router;
$this->encoder = $encoder;
}
public function getCredentials(Request $request)
{
if ($request->getPathInfo() != '/login_check') {
return;
}
$email = $request->request->get('_email');
$request->getSession()->set(Security::LAST_USERNAME, $email);
$password = $request->request->get('_password');
return [
'email' => $email,
'password' => $password,
];
}
public function getUser($credentials, UserProviderInterface $userProvider)
{
$email = $credentials['email'];
return $userProvider->loadUserByUsername($email);
}
public function checkCredentials($credentials, UserInterface $user)
{
$plainPassword = $credentials['password'];
if ($this->encoder->isPasswordValid($user, $plainPassword)) {
return true;
}
throw new BadCredentialsException();
}
public function onAuthenticationSuccess(Request $request, TokenInterface $token, $providerKey)
{
$url = $this->router->generate('welcome');
return new RedirectResponse($url);
}
public function onAuthenticationFailure(Request $request, AuthenticationException $exception)
{
$request->getSession()->set(Security::AUTHENTICATION_ERROR, $exception);
$url = $this->router->generate('login');
return new RedirectResponse($url);
}
protected function getLoginUrl()
{
return $this->router->generate('login');
}
protected function getDefaultSuccessRedirectUrl()
{
return $this->router->generate('welcome');
}
public function supportsRememberMe()
{
return false;
}
}
但是它显示以下错误:
(1/1)FatalErrorException 错误:类App \ Security \ FormLoginAuthenticator包含1个抽象方法,因此必须声明为抽象或实现其余方法(Symfony \ Component \ Security \ Guard \ AuthenticatorInterface :: supports)
能否请您提供任何线索,该类的哪个抽象方法导致此错误?
答案 0 :(得分:1)
Symfony\Component\Security\Guard\Authenticator\AbstractFormLoginAuthenticator
的子类必须实现以下抽象方法:
/**
* Return the URL to the login page.
*
* @return string
*/
protected function getLoginUrl()
/**
* Does the authenticator support the given Request?
*
* If this returns false, the authenticator will be skipped.
*
* @param Request $request
*
* @return bool
*/
public function supports(Request $request)
/**
* Get the authentication credentials from the request and return them
* as any type (e.g. an associate array).
*
* Whatever value you return here will be passed to getUser() and checkCredentials()
*
* For example, for a form login, you might:
*
* return array(
* 'username' => $request->request->get('_username'),
* 'password' => $request->request->get('_password'),
* );
*
* Or for an API token that's on a header, you might use:
*
* return array('api_key' => $request->headers->get('X-API-TOKEN'));
*
* @param Request $request
*
* @return mixed Any non-null value
*
* @throws \UnexpectedValueException If null is returned
*/
public function getCredentials(Request $request)
/**
* Return a UserInterface object based on the credentials.
*
* The *credentials* are the return value from getCredentials()
*
* You may throw an AuthenticationException if you wish. If you return
* null, then a UsernameNotFoundException is thrown for you.
*
* @param mixed $credentials
* @param UserProviderInterface $userProvider
*
* @throws AuthenticationException
*
* @return UserInterface|null
*/
public function getUser($credentials, UserProviderInterface $userProvider)
/**
* Returns true if the credentials are valid.
*
* If any value other than true is returned, authentication will
* fail. You may also throw an AuthenticationException if you wish
* to cause authentication to fail.
*
* The *credentials* are the return value from getCredentials()
*
* @param mixed $credentials
* @param UserInterface $user
*
* @return bool
*
* @throws AuthenticationException
*/
public function checkCredentials($credentials, UserInterface $user)
/**
* Called when authentication executed and was successful!
*
* This should return the Response sent back to the user, like a
* RedirectResponse to the last page they visited.
*
* If you return null, the current request will continue, and the user
* will be authenticated. This makes sense, for example, with an API.
*
* @param Request $request
* @param TokenInterface $token
* @param string $providerKey The provider (i.e. firewall) key
*
* @return Response|null
*/
public function onAuthenticationSuccess(Request $request, TokenInterface $token, $providerKey)
您会在错误中看到,由于缺少方法supports
答案 1 :(得分:1)
在AbstractFormLoginAuthenticator类中编写:
public function supports(Request $request)
{
return 'app_login' === $request->attributes->get('_route')
&& $request->isMethod('POST');
}
“ app_login”是名称控制器登录名