以编程方式登录并保持登录状态 [英] Login programmatically and stay logged in

查看:89
本文介绍了以编程方式登录并保持登录状态的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用Symfony2实现对网站的单点登录.

I'm trying to implement single sign on access to a website using Symfony2.

身份验证本身似乎可以正常工作,但仅适用于初始页面.在加载的下一页上,用户不再登录.

The authentication itself seems to work fine, but only for the initial page. On the next page that is loaded the user is not logged in anymore.

相关代码:

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

首页(不带重定向):

第二页:

推荐答案

自定义登录仅需要以下代码.

Only the following code is necessary for custom log-in.

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

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

这是在安全上下文中设置UsernamePasswordToken.该令牌(以及用户)将被序列化并放入会话中.在下一页上,令牌将从会话中取消序列化,并且还将刷新也未序列化的用户.

What this does is setting the UsernamePasswordToken in the security context. This token (and also the user) will be serialized and put in the session. On the next page the the token will be unserialized from the session and the, also unserialized, user will be refreshed.

FOSUserBundle中的用户提供者使用未序列化用户的ID进行刷新.

The user-provider in the FOSUserBundle does this refreshing using the id of the unserialized user.

此外,在某些情况下,Doctrine2使用代理类作为实体类,而不是原始的实体类.该代理类通过复杂的延迟加载复杂的实现覆盖了实体的"getId()"功能.

Also, Doctrine2 in some cases uses proxy-classes as entity-classes instead of the original entity class. This proxy-class overwrites the "getId()" function of the entity by a complex lazy-loading complex implementation.

这可能导致一个事实,当您将Doctrine2代理对象放入UserPasswordToken中时,序列化然后未序列化的代理对象的"getId()"将不会返回原始ID.发生这种情况时,用户提供者将无法刷新用户,令牌将变得无效.

This together could lead to the fact that, when you put the Doctrine2 proxy-object in the UserPasswordToken, the "getId()" of the serialized and then unserialized proxy-object will not return the original id. When that happens the user can not be refreshed by the user-provider, and the token will become invalid.

对此的一种解决方法是创建一个自定义用户提供程序,该刷新程序使用用户名(或其他唯一属性)来覆盖"refreshUser()".

A fix for this is creating a custom user-provider that overwrites the "refreshUser()" by a refreshing using the username (or an other unique property).

//...
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;
    }
}

这篇关于以编程方式登录并保持登录状态的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆