В Symfony 4.3 можно принудительно разлогинить пользователя по его идентификатору (ID) с помощью класса TokenProviderInterface
и сервиса security.token_storage
. Вот как это сделать:
1. Сначала необходимо создать сервис, который будет использоваться для разлогинивания пользователя. Для этого создаем новый класс, например, ForceLogoutService
.
// src/Service/ForceLogoutService.php namespace AppService; use SymfonyComponentSecurityCoreAuthenticationTokenStorageTokenStorageInterface; use SymfonyComponentSecurityCoreExceptionAuthenticationException; use SymfonyComponentSecurityCoreExceptionLogoutException; use SymfonyComponentSecurityCoreAuthenticationTokenTokenInterface; use SymfonyComponentSecurityCoreAuthenticationTokenUsernamePasswordToken; use SymfonyComponentSecurityCoreAuthenticationTokenPreAuthenticatedToken; class ForceLogoutService { private $tokenStorage; public function __construct(TokenStorageInterface $tokenStorage) { $this->tokenStorage = $tokenStorage; } public function logoutUserById(int $userId): void { // Получаем текущий токен пользователя $currentToken = $this->tokenStorage->getToken(); if (!$currentToken instanceof UsernamePasswordToken && !$currentToken instanceof PreAuthenticatedToken) { throw new AuthenticationException('Invalid token type.'); } // Проверяем, совпадает ли ID пользователя с переданным ID $user = $currentToken->getUser(); if ($user instanceof UserInterface && $user->getId() === $userId) { // Удаляем токен из хранилища $this->tokenStorage->setToken(null); // Генерируем исключение для принудительного разлогинивания throw new LogoutException('Force logout.'); } } }
2. Затем необходимо зарегистрировать этот сервис в контейнере зависимостей Symfony. Для этого открываем файл services.yaml
в директории config
и добавляем следующую строчку:
# config/services.yaml AppServiceForceLogoutService: arguments: - '@security.token_storage'
3. Теперь мы можем использовать сервис ForceLogoutService
для разлогинивания пользователя по его ID. В контроллере или другом месте приложения, где необходимо разлогинить пользователя, добавляем инъекцию зависимости сервиса:
// src/Controller/YourController.php namespace AppController; use AppServiceForceLogoutService; use SymfonyComponentRoutingAnnotationRoute; class YourController extends AbstractController { private $forceLogoutService; public function __construct(ForceLogoutService $forceLogoutService) { $this->forceLogoutService = $forceLogoutService; } /** * @Route("/logout/{userId}", name="logout_by_id") */ public function logoutById(int $userId) { $this->forceLogoutService->logoutUserById($userId); // Редирект или другие действия после разлогинивания пользователя } }
Теперь, когда пользователь обращается по пути /logout/{userId}
, сервис ForceLogoutService
проверяет, совпадает ли переданный ID с текущим пользователем. Если да, то происходит принудительное разлогинивание пользователя.