我目前在Symfony 4中遇到会话管理问题而我无法找到问题所在。 首先是框架配置:
framework:
secret: '%env(APP_SECRET)%'
default_locale: '%env(DEFAULT_LOCATE)%'
#csrf_protection: true
#http_method_override: true
# Enables session support. Note that the session will ONLY be started if you read or write from it.
# Remove or comment this section to explicitly disable session support.
session:
handler_id: session.handler.native_file
save_path: /tmp/registration
#save_path: '%kernel.project_dir%/var/sessions/%kernel.environment%'
#esi: true
#fragments: true
php_errors:
log: true
cache:
# Put the unique name of your app here: the prefix seed
# is used to compute stable namespaces for cache keys.
#prefix_seed: your_vendor_name/app_name
# The app cache caches to the filesystem by default.
# Other options include:
# Redis
#app: cache.adapter.redis
#default_redis_provider: redis://localhost
# APCu (not recommended with heavy random-write workloads as memory fragmentation can cause perf issues)
#app: cache.adapter.apcu
安全配置
parameters:
remember_me_field: '_remember_me'
security:
access_control:
-
path: ^/backend
roles: ROLE_USER
#requires_channel: https
-
path: ^/admin
roles: ROLE_USER
#requires_channel: https
-
path: ^/security/login/form
roles: IS_AUTHENTICATED_ANONYMOUSLY
#requires_channel: https
-
path: ^/security/login/authenticate
roles: IS_AUTHENTICATED_ANONYMOUSLY
#requires_channel: https
-
path: ^/security/logout
roles: ROLE_USER
#requires_channel: https
# https://symfony.com/doc/current/book/security.html#where-do-users-come-from-user-providers
encoders:
Symfony\Component\Security\Core\User\UserInterface:
algorithm: bcrypt
cost: 12
firewalls:
dev:
pattern: ^/(_(profiler|wdt)|css|images|js)/
security: false
main:
anonymous: ~
logout:
path: /security/login/logout
target: /security/login/form
guard:
authenticators:
- App\Security\LoginAuthenticator
remember_me:
secret: '%kernel.secret%'
lifetime: 31557600 # 1 year in seconds
path: /
remember_me_parameter: '%remember_me_field%'
default:
switch_user:
provider: ~
parameter: _switch_user
role: PERMISSION_ALLOWED_TO_SWITCH
pattern: ^/
anonymous: ~
provider: mjr_one
providers:
provider:
entity:
class: App\Entity\User\User
property: email
role_hierarchy:
#User Type Roles
ROLE_GUEST:
ROLE_USER:
和守卫登录
<?php
declare(strict_types=1);
namespace App\Security;
use App\Entity\User\User;
use Symfony\Bridge\Doctrine\Security\User\EntityUserProvider;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException;
use Symfony\Component\DependencyInjection\Exception\ServiceCircularReferenceException;
use Symfony\Component\DependencyInjection\Exception\ServiceNotFoundException;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Exception\InvalidParameterException;
use Symfony\Component\Routing\Exception\MissingMandatoryParametersException;
use Symfony\Component\Routing\Exception\RouteNotFoundException;
use Symfony\Component\Routing\Router;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\Security\Core\Encoder\UserPasswordEncoder;
use Symfony\Component\Security\Core\Exception\AuthenticationCredentialsNotFoundException;
use Symfony\Component\Security\Core\Exception\AuthenticationException;
use Symfony\Component\Security\Core\Exception\CustomUserMessageAuthenticationException;
use Symfony\Component\Security\Core\Exception\UsernameNotFoundException;
use Symfony\Component\Security\Core\Security;
use Symfony\Component\Security\Core\User\UserInterface;
use Symfony\Component\Security\Core\User\UserProviderInterface;
use Symfony\Component\Security\Guard\AbstractGuardAuthenticator;
/**
* Class LoginAuthenticator
*
* @package app\Security
* @author Chris Westerfield <chris@app.one>
* @link http://www.app.one
* @license properitary
* @copyright Chris
*/
class LoginAuthenticator extends AbstractGuardAuthenticator
{
//Routing
protected const LOGIN_FORM = '/security/login/login';
protected const ROUTER_LOGIN = 'security_login_login';
protected const ROUTER_FORM = 'security_login_form';
//Form
protected const LOGIN_FORM_USERNAME_FIELD = '_username';
protected const LOGIN_FORM_USERNAME_PASSWORD = '_password';
//Backend
protected const BACKEND_INDEX = 'backend_index_index';
protected const ROLE_BACKEND = 'ROLE_TENANT';
//Admin
protected const ROLE_ADMIN = 'ROLE_ADMIN';
protected const ADMIN_INDEX = 'admin_index_index';
//User
protected const USER_INDEX = 'index_index';
/**
* Default message for authentication failure.
*
* @var string
*/
protected $failMessage = 'Invalid credentials';
/**
* @var UserPasswordEncoder
*/
protected $encoder;
/**
* @var Router
*/
protected $router;
/**
* @var ContainerInterface
*/
protected $container;
/**
* Authenticator constructor.
*
* @param Router $router
* @param UserPasswordEncoder $encoder
* @param ContainerInterface $container
*/
public function __construct(Router $router, UserPasswordEncoder $encoder, ContainerInterface $container)
{
$this->router = $router;
$this->encoder = $encoder;
$this->container = $container;
}
/**
* @param Request $request
*
* @return array|mixed|null
*/
public function getCredentials(Request $request)
: array {
if ($request->getPathInfo() !== self::LOGIN_FORM || !$request->isMethod('POST')) {
return [
self::LOGIN_FORM_USERNAME_FIELD => null,
];
}
$user = [
self::LOGIN_FORM_USERNAME_FIELD => $request->request->get(self::LOGIN_FORM_USERNAME_FIELD),
self::LOGIN_FORM_USERNAME_PASSWORD => $request->request->get(self::LOGIN_FORM_USERNAME_PASSWORD),
];
return $user;
}
/**
* @param mixed $credentials
* @param UserProviderInterface $userProvider
*
* @return null|UserInterface
* @throws CustomUserMessageAuthenticationException
*/
public function getUser($credentials, UserProviderInterface $userProvider)
: ?UserInterface {
if (!$userProvider instanceof EntityUserProvider && !$userProvider instanceof UserProviderInterface) {
return null;
}
try {
return $userProvider->loadUserByUsername($credentials[self::LOGIN_FORM_USERNAME_FIELD]);
} catch (UsernameNotFoundException $e) {
throw new CustomUserMessageAuthenticationException($this->failMessage);
}
}
/**
* @param mixed $credentials
* @param UserInterface|User $user
*
* @return bool
* @throws CustomUserMessageAuthenticationException
*/
public function checkCredentials($credentials, UserInterface $user)
: bool {
/** @var User $encoded */
$plainPassword = $credentials[self::LOGIN_FORM_USERNAME_PASSWORD];
return $this->encoder->isPasswordValid($user, $plainPassword);
}
/**
* @param Request $request
* @param TokenInterface $token
* @param string $providerKey
*
* @return null|Response
* @throws \InvalidArgumentException
* @throws RouteNotFoundException
* @throws MissingMandatoryParametersException
* @throws InvalidParameterException
* @throws AuthenticationCredentialsNotFoundException
* @throws InvalidArgumentException
* @throws ServiceNotFoundException
* @throws ServiceCircularReferenceException
*/
public function onAuthenticationSuccess(Request $request, TokenInterface $token, $providerKey)
: ?Response {
/** @var User $user */
$user = $token->getUser();
$roles = $user->getRoles();
$validation = $this->container->get('security.authorization_checker');
if ($validation->isGranted(self::ROLE_BACKEND)) {
$url = $this->router->generate(self::BACKEND_INDEX);
} else {
if ($validation->isGranted(self::ROLE_ADMIN)) {
$url = $this->router->generate(self::ADMIN_INDEX);
} else {
$url = $this->router->generate(self::USER_INDEX);
}
}
return new RedirectResponse($url);
}
/**
* @param Request $request
* @param AuthenticationException $exception
*
* @return null|Response
* @throws \InvalidArgumentException
*/
public function onAuthenticationFailure(Request $request, AuthenticationException $exception)
: ?Response {
$request->getSession()->set(Security::AUTHENTICATION_ERROR, $exception);
$url = $this->router->generate(self::ROUTER_FORM);
return new RedirectResponse($url);
}
/**
* @param Request $request
* @param AuthenticationException|null $authException
*
* @return Response
* @throws RouteNotFoundException
* @throws MissingMandatoryParametersException
* @throws \InvalidArgumentException
* @throws InvalidParameterException
*/
public function start(Request $request, AuthenticationException $authException = null)
: Response {
$url = $this->router->generate(self::ROUTER_LOGIN);
return new RedirectResponse($url);
}
/**
* @return bool
*/
public function supportsRememberMe()
: bool
{
$request = $this->container->get('request_stack')->getCurrentRequest();;
$field = $this->container->getParameter('remember_me_field');
return $request->request->has($field);
}
/**
* @param Request $request
*
* @return bool
*/
public function supports(Request $request)
: bool {
if ($request->getMethod() === 'POST' && $request->request->has(self::LOGIN_FORM_USERNAME_FIELD) && $request->request->has(self::LOGIN_FORM_USERNAME_PASSWORD)) {
return true;
}
return false;
}
}
我的问题是我总是得到一个新的会话ID。 但我不知道我在哪里错误配置了Symfony。 即使是记忆选项也没有帮助 我还认识到,security.token不包含任何令牌。 我对系统进行了调试,并认识到每次请求都会触发destroy方法。 但我不知道我发生了什么事情。 任何帮助都是有效的
: - )
克里斯
到目前为止我发现的是:
如果我查看&#39; @ security.token_storage&#39;的内容。我得到了什么服务
TokenStorage {#1180 ▼
-token: null
}
但如果我在控制器中检查它:
我明白了:
TokenStorage {#1180 ▼
-token: RememberMeToken {#2357 ▶}
}
在日志中我没有看到任何错误。对我来说似乎很奇怪的唯一部分是:
这对我来说很奇怪。
在我忘记之前,我使用Symfony 4.0.10和php 7.2.5
答案 0 :(得分:0)
查看了所有服务后,我发现了它。 我计划在过滤器中使用需要令牌存储的服务。 目前在我看来,这个服务获得一个空的空token_storage,它会覆盖所有未来的实例。 我删除了监听器,系统按预期再次工作。