1

如果用户会话在 X 秒内处于非活动状态,我会尝试使用户会话过期。我找到了很多解决方案来做到这一点,但不是针对非活动会话。

我使用 Symfony2 和 Guard Authentification。我已经实现了这个解决方案,这似乎还不错。但是即使用户处于活动状态,会话也会过期。我可能想念一些东西。使用 Guard 是否有任何特殊性会影响会话时间?

我的身份验证器

<?php

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

我的会话处理程序:

<?php

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

}

服务.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 }

配置.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

parameters.yml我有这个:sessionLifeTime: 0

我也找到了这个选项,但它可以解决我的问题吗?

4

2 回答 2

0

最简单的方法是通过合理频繁地运行的垃圾收集来实现这一点。

您在 symfony 文档中获得了有关空闲时间会话的段落。

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

于 2016-06-15T09:32:18.547 回答
0

谢谢你的帮助,

我不明白我做了什么。我已经测试了您的解决方案(所以我评论了我的会话处理程序)将gc_maxlifetime放在config.yml上,但我的问题仍然存在。

所以我取消了我的会话处理程序的注释,最后我回到了我之前发布的代码......现在它可以工作了......

对不起,我无法解释。我已经多次清除缓存,所以我认为这不是原因。

于 2016-06-15T14:59:54.260 回答