2013-01-14 5 views
7

Symfony2를 사용하여 웹 사이트에 대한 단일 액세스를 구현하려고합니다.프로그래밍 방식으로 로그인하고 로그인 상태 유지

인증 자체는 정상적으로 작동하지만 첫 페이지에만 제대로 작동하는 것 같습니다. 로드 된 다음 페이지에서 사용자는 더 이상 로그인하지 않습니다.

관련 코드 :

$token = new UsernamePasswordToken($user, null, 'main', $user->getRoles()); 
$event = new InteractiveLoginEvent($request, $token); 

$this->get("event_dispatcher")->dispatch(SecurityEvents::INTERACTIVE_LOGIN, $event); 
$this->get("security.context")->setToken($token); 

return $this->redirect($this->generateUrl('sonata_user_profile_show')); 

첫 페이지 (리디렉션없이)

Initial page - logged in

번째 페이지 :

Second page - Not logged in anymore

+0

Symfony 2.1을 사용하고 있습니까? 그렇다면 다음 줄을 추가해보십시오 : '$ session-> set ('_ security_'. $ firewallName, serialize ($ token)); $ session-> save(); ' – Squazic

+0

내가 작업하고있는 ASP.NET 웹 앱에서 이와 같은 문제가 발생했습니다. 내 브라우저에서 캐시를 지우고 다시 작동하기 시작했습니다. 바라기를 너무 쉽게 당신을 위해 :) – Anonymous

+0

@ 스쿼시 예, 나는 Symfony 2.1을 사용하고 있습니다. 세션 스 니펫을 추가했지만 불행히도 작동하지 않았습니다. –

답변

6

맞춤 로그인에 필요한 코드는 다음과 같습니다.

$token = new UsernamePasswordToken($user, null, 'main', $user->getRoles()); 
$this->get("security.context")->setToken($token); 

return $this->redirect($this->generateUrl('sonata_user_profile_show')); 

이것은 보안 컨텍스트에서 UsernamePasswordToken을 설정하는 것입니다. 이 토큰 (및 사용자)은 일련 화되어 세션에 저장됩니다. 다음 페이지에서 토큰은 세션에서 비 직렬화되며 직렬화되지 않은 사용자도 새로 고쳐집니다.

FOSUserBundle의 사용자 공급자는 직렬화되지 않은 사용자의 ID를 사용하여이 새로 고침을 수행합니다.

또한 Doctrine2는 프록시 클래스를 원래 엔터티 클래스 대신 엔터티 클래스로 사용합니다. 이 프록시 클래스는 복잡한 지연로드 복잡한 구현에 의해 엔티티의 "getId()"기능을 덮어 씁니다.

Doctrine2 프록시 개체를 UserPasswordToken에 넣으면 직렬화 된 다음 직렬화되지 않은 프록시 개체의 "getId()"가 원래 ID를 반환하지 않는다는 사실이 발생할 수 있습니다. 이 경우 사용자가 사용자 공급자에 의해 새로 고칠 수 없으며 토큰이 유효하지 않게됩니다.

이 문제를 해결하려면 사용자 이름 (또는 다른 고유 한 속성)을 사용하여 새로 고침하여 "refreshUser()"를 덮어 쓰는 사용자 지정 사용자 공급자를 만들어야합니다.

//... 
class UserProvider extends FOSUserProvider 
{ 
    /** 
    * {@inheritDoc} 
    */ 
    public function refreshUser(SecurityUserInterface $user) 
    { 
     if (!$user instanceof User) { 
      throw new UnsupportedUserException(sprintf('Expected an instance of User, but got "%s".', get_class($user))); 
     } 

     if (null === $reloadedUser = $this->userManager->findUserBy(array('username' => $user->getUsername()))) { 
      throw new UsernameNotFoundException(sprintf('User with username "%s" could not be reloaded.', $user->getUsername())); 
     } 

     return $reloadedUser; 
    } 
} 
관련 문제