简体   繁体   English

Symfony2保护非活动会话生命周期

[英]Symfony2 guard inactive session lifetime

I try to expire user session if it's inactive for X seconds. 如果用户会话在X秒内处于非活动状态,我会尝试使用户会话失效。 I've find many solutions to do that, but not for an inactive session. 我找到了许多解决方案,但不适用于非活动会话。

I use Symfony2 with Guard Authentification. 我使用Symfony2和Guard Authentification。 I've implemented this solution , which seems not bad. 我已经实现了这个解决方案 ,看起来不错。 But the session expire, even if the user is active. 但即使用户处于活动状态,会话也会过期。 I probably miss something. 我可能会错过一些东西 Is there any particularity to use Guard that can affect session time ? 使用Guard可以影响会话时间有什么特别之处吗?

My Authenticator : 我的身份验证员

namespace AppBundle\Security;


class TokenAuthenticator extends AbstractGuardAuthenticator
{
    /**
   * @var \Symfony\Component\Routing\RouterInterface
   */
    private $router;

    /*
     * Url d'accès au WebService d'authentification
     */
    private $urlWs;

    /**
     * Constructeur
     * @param RouterInterface $router
     * @param string $urlWs : Url d'accès au WebService d'authentification
     */
    public function __construct(RouterInterface $router, $urlWs) {
        $this->router = $router;
        $this->urlWs = $urlWs;
    }


    /**
     * Called on every request. Return whatever credentials you want,
     * or null to stop authentication.
     */
    public function getCredentials(Request $request)
    {
        if ($request->getPathInfo() != "/login_check"){
            return;
        }

        // What you return here will be passed to getUser() as $credentials
        return [
            'login' => $request->request->get('username'),
            'password' => $request->request->get('password'),
            'request' => $request,
        ];
    }

    /**
     * 
     * @param type $credentials
     * @param UserProviderInterface $userProvider
     * @return User
     */
    public function getUser($credentials, UserProviderInterface $userProvider)
    {
       $login = $credentials['login'];

       $user = new User();
       $user->setLogin($login);

       return $user;
    }

    public function checkCredentials($credentials, UserInterface $user)
    {        
        $username = $credentials['login'];
        $password = $credentials['password'];           
        try {
                /**********************************
                Call my WebService to control the login password
                If it's ok, I save the returned user in session
                *****************************************/

                return true;
            } else {
                throw new CustomUserMessageAuthenticationException($ws_response->messages[0]);
            }               
        }catch(\Exception $e){
            throw $e;
        }  
    }


    public function onAuthenticationSuccess(Request $request, TokenInterface $token, $providerKey)
    {
        $session = $request->getSession();     
        $url = "/";
        return new RedirectResponse($url);
    }

    public function onAuthenticationFailure(Request $request, AuthenticationException $exception)
    {
        $request->getSession()->set(Security::AUTHENTICATION_ERROR, $exception);
        $url = $this->router->generate('loginSf');
        return new RedirectResponse($url);
    }

    /**
     * Called when authentication is needed, but it's not sent
     */
    public function start(Request $request, AuthenticationException $authException = null)
    {
        $url = $this->router->generate('loginSf');
        return new RedirectResponse($url);
    }

    public function supportsRememberMe()
    {
        return false;
    }
}

My session handler: 我的会话处理程序

namespace AppBundle\Handler;

class SessionIdleHandler
{

    protected $session;
    protected $securityContext;
    protected $router;
    protected $maxIdleTime;

    public function __construct(SessionInterface $session, SecurityContextInterface $securityContext, RouterInterface $router, $maxIdleTime = 0)
    {
        $this->session = $session;
        $this->securityContext = $securityContext;
        $this->router = $router;
        $this->maxIdleTime = $maxIdleTime;
    }

    public function onKernelRequest(GetResponseEvent $event)
    {
        if (HttpKernelInterface::MASTER_REQUEST != $event->getRequestType()) {

            return;
        }

        if ($this->maxIdleTime > 0) {

            $this->session->start();
            $lapse = time() - $this->session->getMetadataBag()->getLastUsed();

            if ($lapse > $this->maxIdleTime) {

                $this->securityContext->setToken(null);
                $this->session->getFlashBag()->set('info', 'You have been logged out due to inactivity.');

                $event->setResponse(new RedirectResponse($this->router->generate('loginSf')));
            }
        }
    }

}

service.yml : service.yml

services:
    my.handler.session_idle:
        class: AppBundle\Handler\SessionIdleHandler
        arguments: ["@session", "@security.context", "@router", %sessionLifeTime%]
        tags:
            - { name: kernel.event_listener, event: kernel.request, method: onKernelRequest }

config.yml : config.yml

framework:
    secret:          "%secret%"
    router:
        resource: "%kernel.root_dir%/config/routing.yml"
        strict_requirements: ~
    form:            ~
    csrf_protection: ~
    validation:      { enable_annotations: true }
    templating:
        engines: ['twig']
    default_locale:  "%locale%"
    trusted_hosts:   ~
    trusted_proxies: ~
    session:
        cookie_lifetime: %sessionLifeTime% 
        # handler_id set to null will use default session handler from php.ini
        handler_id:  ~
    fragments:       ~
    http_method_override: true

And in parameters.yml I've this : sessionLifeTime: 0 parameters.yml我这样: sessionLifeTime: 0

I found this option too, but is it a solution to my problem ? 我也找到了这个选项 ,但它是解决我的问题的方法吗?

Can you help me ? 你能帮助我吗 ? Thank's. 谢谢。

The easiest way is to implement this via garbage collection which runs reasonably frequently. 最简单的方法是通过合理频繁运行的垃圾收集来实现这一点。

You got a paragraph on the symfony doc concerning idle time session. 你有一个关于空闲时间会话的symfony doc的段落。

http://symfony.com/doc/current/components/http_foundation/session_configuration.html#session-idle-time-keep-alive http://symfony.com/doc/current/components/http_foundation/session_configuration.html#session-idle-time-keep-alive

Thank's for your help, 谢谢你的帮助,

I do not understand what I've done. 我不明白我做了什么。 I've tested your solution (so I comment my Session Handler) to put gc_maxlifetime on config.yml , but my problem was still there. 我测试您的解决方案(所以我评论我的会话处理器)把gc_maxlifetimeconfig.yml,但我的问题仍然存在。

So I've uncomment my session handler, finally I returned to the code I've post before... and now it works... 所以我取消了对会话处理程序的注释,最后我回到了之前发布的代码......现在它可以工作了......

Sorry I can't explain that. 对不起,我无法解释。 I've cleared the cache many times, so I think it's not the reason. 我已多次清除缓存,所以我认为这不是原因。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM