我是Symfony 2的新手,我需要通过链接和哈希来编写自定义登录代码。 我使用本教程创建了用户提供程序和用户身份验证器 - symfony 2 - api key auth。
登录本身工作正常,但我正在努力“记住我”的功能。 您可以在“SECURITY.yml”的配置摘录中看到代码的相关部分,这会导致错误消息 - “RuntimeException:您必须为每个防火墙配置至少一个记住我的监听器(例如表单登录)记得 - 我启用了。“
security.yml
security:
role_hierarchy:
ROLE_ADMIN: ROLE_USER
ROLE_SUPER_ADMIN: [ROLE_USER, ROLE_ADMIN, ROLE_ALLOWED_TO_SWITCH]
providers:
employee:
id: employee_provider
firewalls:
dev:
pattern: ^/(_(profiler|wdt)|css|images|js)/
security: false
access:
pattern: ^/access$
security: false
main:
pattern: ^/
simple_preauth:
authenticator: employee_authenticator
logout:
path: logout_page
target: forgotten_password_page
invalidate_session: true
remember_me:
key: "%secret%"
lifetime: 3600 # 365 days in seconds
path: /
domain: ~ # Defaults to the current domain from $_SERVER
always_remember_me: true
remember_me_parameter: _remember_me
access_control:
- { path: ^/admin, roles: [ROLE_MASTER] }
EmployeeAuthenticator
class EmployeeAuthenticator implements SimplePreAuthenticatorInterface, AuthenticationSuccessHandlerInterface, AuthenticationFailureHandlerInterface {
protected $router;
protected $httpUtils;
protected $loginCheckUrl;
public function __construct(Router $router, HttpUtils $httpUtils, $loginCheckUrl) {
$this->router = $router;
$this->httpUtils = $httpUtils;
$this->loginCheckUrl = $loginCheckUrl;
}
private function isLoginUrl($request) {
echo rawurldecode($request->getPathInfo());
die();
}
public function createToken(Request $request, $providerKey) {
$this->isLoginUrl($request);
if (!$this->httpUtils->checkRequestPath($request, $this->loginCheckUrl)) {
throw new AuthenticationException("Wrong login page");
}
$apiKey = $request->query->get('apikey');
if (!$apiKey) {
throw new BadCredentialsException('No API key found');
}
return new PreAuthenticatedToken(
'anon.', $apiKey, $providerKey
);
}
public function authenticateToken(TokenInterface $token, UserProviderInterface $userProvider, $providerKey) {
$apiKey = $token->getCredentials();
$employee = $token->getUser();
if ($employee instanceof Employee) {
return new PreAuthenticatedToken(
$employee, $apiKey, $providerKey, $employee->getRoles()
);
}
$employee = $userProvider->loadUserByUsername($apiKey);
if (!$employee) {
throw new AuthenticationException(
sprintf('API Key "%s" does not exist.', $apiKey)
);
}
return new PreAuthenticatedToken(
$employee, $apiKey, $providerKey, $employee->getRoles()
);
}
public function supportsToken(TokenInterface $token, $providerKey) {
return $token instanceof PreAuthenticatedToken && $token->getProviderKey() === $providerKey;
}
public function onAuthenticationFailure(Request $request, AuthenticationException $exception) {
$request->getSession()->getFlashBag()->add('notice', $exception->getMessage());
return new RedirectResponse($this->router->generate('forgotten_password_page'));
}
public function onAuthenticationSuccess(Request $request, TokenInterface $token) {
return new RedirectResponse($this->router->generate('homepage'));
}
}
EmployeeProvider
class EmployeeProvider implements UserProviderInterface {
private $repo;
public function __construct(ObjectManager $em) {
$this->repo = $em->getRepository("MyWebBundle:Employee");
}
public function loadUserByUsername($hash) {
$employee = $this->repo->loadUserByHash($hash);
if ($employee) {
return $employee;
}
throw new UsernameNotFoundException(
sprintf('ApiKey is not exists "%s" does not exist.', $hash)
);
}
public function refreshUser(UserInterface $employee) {
if (!$employee instanceof Employee) {
throw new UnsupportedUserException(
sprintf('Instances of "%s" are not supported.', get_class($employee))
);
}
return $this->repo->findOneById($employee->getId());
}
public function supportsClass($class) {
return $class === 'My\WebBundle\Entity\Employee';
}
}