Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
408 views
in Technique[技术] by (71.8m points)

php - Session expires even if I'm working, session lifetime, Ajax and Symfony2

I have configured my application for close session on timeout if user do nothing during 10 minutes period. At config.yml I have this:

session:
    handler_id:  ~
    cookie_lifetime: 600 # 10 minutes
    gc_maxlifetime: 600 # 10 minutes
    gc_probability: 1
    gc_divisor: 1

I do a Ajax call every one minute to check if session will be close to expire or doesn't and this is what I check:

public function isLoggedInAction(Request $request)
{
    $response = array();
    $response['authenticated'] = FALSE;
    $status = 200;
    $securityContext = $this->container->get('security.context');
    if ($securityContext->isGranted('IS_AUTHENTICATED_FULLY')) {
        $response['authenticated'] = TRUE;
    }

    return new JsonResponse($response, $status ?: 200);
}

For some unknow reason is not working and every 10 minutes session is closed whether I'm working with page or doesn't, why? I'm missing something?

Edit 1 Tried new values, still not working:

session:
    handler_id:  ~
    cookie_lifetime: 1800
    gc_maxlifetime: 600
    gc_probability: 1
    gc_divisor: 100

While I was working on the page, performing Ajax calls and some other tasks the session was closed so is not working. The only value that apparently works for me til now is set cookie_lifetime: 86400 #1 day which is crazy to me!

Edit 2 After @acontell suggestion for fix the VM time and date I'm trying with this new values (10 minutes takes too long so I've changed to 3):

session:
    handler_id:  ~
    cookie_lifetime: 1800
    gc_maxlifetime: 180 # session will expire after 3 minutes of inactivity
    gc_probability: 1
    gc_divisor: 100

And also I fixed the date/time on the VM by enabling ntpd service and now date is just fine:

[root@webvm var]# date
 Sun Feb  1 18:35:17 VET 2015

But after 5 minutes (function call was executed 5 times) session still alive. This is how I call the function isLoggedInAction() from Javascript side:

$.post(Routing.generate('isLoggedIn',{}),{},'json').done(function (data, textStatus, jqXHR){
    if( data.authenticated ){
        var timer = window.setInterval(function(){
            $.post(Routing.generate('isLoggedIn',{}),{},'json').done(function (data, textStatus, jqXHR){
                if( !data.authenticated ){
                    window.clearInterval(timer);
                    $.growl({
                        message: 'La sesión ha expirado por inactividad, debe <a href=""><b>iniciar seción</b></a> nuevamente.'
                    }, {
                        type: "danger",
                        allow_dismiss: false,
                        timer: 10000,
                        animate: {
                            enter: 'animated fadeInDown',
                            exit: 'animated fadeOutUp'
                        },
                        onHide: function(){
                            location.reload();
                        }
                    });
                }
            }).fail(function(){});
        },60000);
    }
}).fail(function(){});

See the image below:

enter image description here

Test 3

After say all was working fine I did the latest and definitive test: open the application and leave untouched during all the night (almost 8 hours) and surprise it never closes the session. As image below show see how many request the page does and see how session still alive, why?

enter image description here

Ajax call is made every: 10.5 minutes

$.post(Routing.generate('isLoggedIn',{}),{},'json').done(function (data, textStatus, jqXHR){
    if( data.authenticated ){
        var timer = window.setInterval(function(){
            $.post(Routing.generate('isLoggedIn',{}),{},'json').done(function (data, textStatus, jqXHR){
                if( !data.authenticated ){
                    window.clearInterval(timer);
                    $.growl({
                        message: 'La sesión ha expirado por inactividad, debe <a href=""><b>iniciar seción</b></a> nuevamente.'
                    }, {
                        type: "danger",
                        allow_dismiss: false,
                        timer: 10000,
                        animate: {
                            enter: 'animated fadeInDown',
                            exit: 'animated fadeOutUp'
                        },
                        onHide: function(){
                            location.reload();
                        }
                    });
                }
            }).fail(function(){});
        }, 210000);
    }
}).fail(function(){});

Settings say that session should expire passed: 10 minutes.

session:
    handler_id:  ~
    cookie_lifetime: 630000
    gc_maxlifetime: 630000 # session will expire after 10 minutes of inactivity 
    gc_probability: 1
    gc_divisor: 100

Time at server is fine:

[root@webvm sencamer.dev]# date
Mon Feb  2 07:26:53 VET 2015

What else should I check?

Test 5

Ok, I'm still doing test because this has not a good behavior. So, this is what I've do for this test:

  • Open the application and start working on it
  • At some moment stop working and leave the the application made the Ajax call to check whether session still alive or not. (session still alive see image below)
  • After that first call I continue working on the application as image 2 shows but surprise session ends and the application gets close.

Why? What is causing that behavior? Is that right based on my parameters?

This image shows the first and only call to the function

enter image description here

After the call was made I continue working but session gets closed

enter image description here

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

First, watch out your gc_probability and gc_divisor. If both are set to one, that means that the probability that the garbage collector (GC) process is started on every session initialization is gc_probability / gc_divisor = 1/1 = 1 (100%).

You could leave it to the defaults or give it a higher number in order to reduce the chance of the GC being called.

For instance:

session:
        # handler_id set to null will use default session handler from php.ini
        handler_id:  ~
        cookie_lifetime: 600 # Ten minutes
        gc_probability: 1
        gc_divisor: 10000

Also, if you're using a Virtual Machine, check the date of your server, the resulting session cookie will be stamped with an expiry time of time() + cookie_lifetime where the time is taken from the server.

It could be possible that, if the server had a bad date, the cookie would expire inmediately. Imagine: server date 2015-01-31, your browser 2015-02-01. Server sends cookie that expires on 2015-01-31 at 11pm, your browser receives a cookie with an expiration date that has already passed.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...