Nic*_*ink 7 php login symfony fosuserbundle symfony-2.1
我正在尝试使用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'));
Run Code Online (Sandbox Code Playgroud)
第一页(没有重定向):

第二页:

自定义登录只需要以下代码.
$token = new UsernamePasswordToken($user, null, 'main', $user->getRoles());
$this->get("security.context")->setToken($token);
return $this->redirect($this->generateUrl('sonata_user_profile_show'));
Run Code Online (Sandbox Code Playgroud)
这样做是在安全上下文中设置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;
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1020 次 |
| 最近记录: |