맞춤 로그인에 필요한 코드는 다음과 같습니다.
$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;
}
}
Symfony 2.1을 사용하고 있습니까? 그렇다면 다음 줄을 추가해보십시오 : '$ session-> set ('_ security_'. $ firewallName, serialize ($ token)); $ session-> save(); ' – Squazic
내가 작업하고있는 ASP.NET 웹 앱에서 이와 같은 문제가 발생했습니다. 내 브라우저에서 캐시를 지우고 다시 작동하기 시작했습니다. 바라기를 너무 쉽게 당신을 위해 :) – Anonymous
@ 스쿼시 예, 나는 Symfony 2.1을 사용하고 있습니다. 세션 스 니펫을 추가했지만 불행히도 작동하지 않았습니다. –