모든 페이지로드 및 요청을 사용자 정의 감사 테이블에 기록하는 Symfony2 프로젝트에 감사 로깅을 추가하고 있습니다. 이 프로젝트는 Symfony2 (방문/로그 아웃)의 기본 로그 아웃 경로를 사용하여 세션을 파괴 한 다음/login 경로로 리디렉션합니다.Symfony2 로그 아웃 이벤트 리스너 이슈
onKernelRequest에 대해 설정된 이벤트 리스너가 올바른 데이터를 테이블에 씁니다. security.yml 파일에서 로그 아웃 경로에 대해 다음을 나열했습니다.
security:
firewalls:
main:
logout:
path: /logout
target: /login
감사 로깅은 logout 이벤트를 제외한 모든 페이지에서 정상적으로 작동합니다. 로그 아웃 한 후 프로파일 러를 방문하여 사이드 바의 "마지막 10"옵션에서 '/ 로그 아웃'작업을 선택하려고했습니다. "Events"를 클릭하면 DebugHandler 및 ProfileListener와 같은 kernel.request의 기본 Symfony 이벤트가 나열되지만 사용자 정의 콜백은 "Not Listed Listeners"탭 아래에 표시됩니다.
security_yml 파일에 추가 할 수있는 success_handler가 있지만 세션이 삭제되기 전에 이벤트 수신기를 실행할 수있는 메서드가 필요합니다. Symfony가 로그 아웃을하기 전에 기존 리스너가 로그 아웃 이벤트를 기록하도록하는 방법이 있습니까?
나는 당신의 Audit logging
서비스에 명확하지 않다으로 편집
<?php
// src/AuditBundle/EventListener/AuditListener.php
namespace AuditBundle\EventListener;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Event\GetResponseEvent;
use Symfony\Component\HttpFoundation\RequestStack;
use AuditBundle\Entity\AuditLog;
class AuditListener
{
protected $requestStack;
protected $em;
protected $tokenStorage;
protected $authorizationChecker;
public function __construct(RequestStack $requestStack, \Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorage $tokenStorage, $authorizationChecker, \Doctrine\ORM\EntityManager $em = NULL)
{
$this->requestStack = $requestStack;
$this->em = $em;
$this->tokenStorage = $tokenStorage;
$this->authorizationChecker = $authorizationChecker;
}
public function onKernelRequest(GetResponseEvent $response)
{
$request = $response->getRequest();
if (strpos($request->getRequestUri(), 'fonts') !== false)
return;
if (strpos($request->getRequestUri(), 'css') !== false)
return;
if (strpos($request->getRequestUri(), '_wdt') !== false)
return;
if (strpos($request->getRequestUri(), 'js') !== false)
return;
if (strpos($request->getRequestUri(), '_profiler') !== false)
return;
$this->log('Request', $request);
}
public function postUpdate(\Doctrine\ORM\Event\LifecycleEventArgs $args)
{
$entity = $args->getEntity();
$this->em = $args->getEntityManager();
$className = $this->em->getClassMetadata(get_class($entity))->getName();
if ($entity instanceof \AuditBundle\Entity\AuditLog)
return;
$this->log($className.' Updated', $this->requestStack->getCurrentRequest(), $entity);
}
public function postPersist(\Doctrine\ORM\Event\LifecycleEventArgs $args)
{
$entity = $args->getEntity();
$this->em = $args->getEntityManager();
$className = $this->em->getClassMetadata(get_class($entity))->getName();
if ($entity instanceof \AuditBundle\Entity\AuditLog)
return;
$this->log($className.' Created', $this->requestStack->getCurrentRequest(), $entity);
}
public function postDelete(\Doctrine\ORM\Event\LifecycleEventArgs $args)
{
$entity = $args->getEntity();
$this->em = $args->getEntityManager();
$className = $this->em->getClassMetadata(get_class($entity))->getName();
if ($entity instanceof \AuditBundle\Entity\AuditLog)
return;
$this->log($className.' Deleted', $this->requestStack->getCurrentRequest());
}
protected function log($message, $request, $entity = NULL)
{
$log = new AuditLog();
$log->setType($request->getRealMethod());
if ($this->authorizationChecker->isGranted('IS_AUTHENTICATED_FULLY'))
{
$log->setUser($this->tokenStorage->getToken()->getUser());
}
if ($entity)
{
$log->setEntityId($entity->getId());
}
$log->setUriString($request->getRequestUri());
$log->setMessage($message);
$log->setDatetime(new \DateTime());
$log->setIp($request->getClientIp());
$log->setBrowser(isset($_SERVER['HTTP_USER_AGENT']) ? $_SERVER['HTTP_USER_AGENT'] : '');
$this->em->persist($log);
$this->em->flush();
}
}
services.yml
services:
audits.audit_listener:
class: AuditBundle\EventListener\AuditListener
arguments: [@request_stack, @security.token_storage, @security.authorization_checker, @doctrine.orm.entity_manager]
tags:
- { name: kernel.event_listener, event: kernel.request }
사용자 지정 콜백 클래스와 해당 서비스를 제공 할 수 있습니까? – Jeet
LogoutHandlerInterface를 구현하고 로그 아웃 처리기가 있다는 것을 설정에 알려야합니다. 내 대답을 참조하십시오. – Prof83