以编程方式登录并保持登录状态

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'));

第一页(不带重定向):

登录后的初始页面

第二页:

未登录时的第二页


你正在使用Symfony 2.1吗?如果是这样,请尝试添加以下行:`$ session->set(' _security_'. $firewallName,serialize($token)); $ session->save();` - Squazic
我曾经在一款我正在开发的ASP.NET网络应用程序上遇到过这样的问题。我清除了浏览器中的缓存,然后它又恢复正常了。希望对你来说也是那么容易 :) - Anonymous
@Squazic 是的,我正在使用Symfony 2.1。我添加了会话片段,但不幸的是它没有起作用。 - Nick Stemerdink
@LuigiSiri 我只想使用会话模拟一个“正常”的登录,而不是使用记住我cookie或类似的东西。顺便说一下,正常的登录工作得很好。 - Nick Stemerdink
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设置在安全上下文中。这个token(以及用户)将被序列化并放在会话中。在下一页中,token将从会话中反序列化,并且也将被反序列化的用户进行刷新。
FOSUserBundle中的用户提供程序使用未序列化用户的ID进行此操作。
另外,Doctrine2在某些情况下使用代理类作为实体类,而不是原始实体类。这个代理类通过一种复杂的延迟加载实现来覆盖实体的“getId()”函数。
这些因素结合起来可能导致当您将Doctrine2代理对象放入UserPasswordToken时,“getId()”无法返回原始ID。当发生这种情况时,用户无法通过用户提供程序进行刷新,令token失效。
解决方法是创建一个自定义用户提供程序,通过使用用户名(或其他唯一属性)来覆盖“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;
    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接