我被分配了在基于symfony的网站上改进身份验证系统的任务。细节并不重要,重要的是新的Guard组件(在Symfony 2.8中引入)非常适合这项任务。
我有以下问题:警卫DO设法验证用户&重定向到主页,但拒绝访问主页(抛出AuthenticationExpiredException),因此用户被重定向回登录。从用户POV,似乎登录总是失败。
即使是一个非常简单的项目,问题也会出现:
/* Not writing getters, setters and annotations here for readability */
class CustomUser implements UserInterface, \Serializable {
private $id;
protected $username;
protected $salt;
protected $password;
public function __construct() {
$this->salt = md5(uniqid(null, true));
}
public function serialize() {
return serialize(array($this->id,));
}
public function unserialize($serialized) {
list($this->id,) = unserialize($serialized);
}
}
Guard类:
class CustomGuardAuthenticator extends AbstractGuardAuthenticator {
private $container;
private $router;
public function __construct(ContainerInterface $container) {
$this->container = $container;
$this->router = $container->get('router');
}
public function start(Request $request, AuthenticationException $authException = null) {
$response = new RedirectResponse($this->router->generate('login'));
return $response;
}
public function getCredentials(Request $request) {
if ($request->getPathInfo() != '/login_check' || !$request->isMethod('POST')) {
return null;
}
return array(
'username' => $request->request->get('_username'),
'password' => $request->request->get('_password'),
);
}
public function getUser($credentials, UserProviderInterface $userProvider) {
$user = $userProvider->loadUserByUsername($credentials['username']); /* No problem here, user correctly fetched */
return $user;
}
public function checkCredentials($credentials, UserInterface $user) {
$encoder = $this->container->get('security.password_encoder');
if (!$encoder->isPasswordValid($user, $credentials['password'])) { /* No problem here either */
throw new BadCredentialsException();
}
return true;
}
public function onAuthenticationFailure(Request $request, AuthenticationException $exception) {
$response = new RedirectResponse($this->router->generate('login'));
return $response;
}
public function onAuthenticationSuccess(Request $request, TokenInterface $token, $providerKey) {
/* Debugging show that we DO reach that */
return new RedirectResponse($this->router->generate('homepage'));
}
public function supportsRememberMe() {
return false;
}
}
security.yml:
security:
encoders:
AppBundle\Entity\CustomUser:
algorithm: sha1
encode_as_base64: false
iterations: 1
providers:
main:
entity: {class: AppBundle\Entity\CustomUser, property: username}
firewalls:
dev:
pattern: ^/(_(profiler|wdt)|css|images|js)/
security: false
main:
pattern: ^/
anonymous: true
guard:
authenticators:
- security.custom.guard
access_control:
- { path: ^/security/*, roles: IS_AUTHENTICATED_ANONYMOUSLY}
- { path: ^/, roles: [ROLE_USER] }
我希望避免使用这3种解决方法中的一种。但最重要的是,我想了解问题是什么,并不觉得最后两天浪费了!
任何帮助将不胜感激:)