Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

troisieme's avatar

Session expire on close

We are currently trying to on of our site to logout user when they close their browser but we are having issues with the feature the user is always logged in even if the browser is closed by the user.

In config/session.php 'lifetime' => 60, 'expire_on_close' => true,

In .env file SESSION_DRIVER=file

Does anyone got the same kind of issues or am I doing something wrong.

0 likes
18 replies
jekinney's avatar

As your server side code will never know when a person closes a browser, your only reliable option is setting a short experation time. But even then let's say you set it for one minute like your code example, a person reads something or takes a quick phone call they will be logged out.

Good luck.

Snapey's avatar

@jekinney is correct. you cannot know if the user just closes their browser. A short timeout will annoy users.

you would need something like laravel-caffeine on every single page to keep the session going.

Why is it an issue?

jlrdw's avatar

@Snapey and @jekinney the OP has

expire_on_close' => true

The OP is saying that user should be logged out. But if they re-open browser they are not logged out. This has got to be a bug. So the question should be why isn't

expire_on_close' => true

Working?
Is there a way to force a logout when closing browser? I know my online pharmacy Express Scripts if you close the browser and then go back online you are definitely logged out. Furthermore why is there a such thing as expire on close if it does not work? Even this stackoverflow mentions it. http://stackoverflow.com/questions/25114267/laravel-auth-session-not-expiring-after-browser-close

Snapey's avatar

@jlrdw @3ejoueur

First of all, you need to appreciate that http operates over temporary connections, and is stateless. When you close a tab, or close your browser or shutdown your machine then NOTHING is sent to the server. The server is none the wiser.

So, what is the point of the expire_on_close flag?

When you start a session with the server, the server sends a session cookie to the client. This session cookie is presented with each request and allows the server to keep track of the user (this has nothing to do with authentication at this point).

With expire_on_close flag set to false, the session cookie has an expiration time of now plus the lifetime setting (by default 2 hours)

With expire_on_close flag set to true, the session cookie has an expiration value of "session". This tells the browser that it should discard the cookie if the user closes the browser tab or the browser itself, even if 2 hours are not up. There is NO impact on the server. When the user closes their browser, if you look at the server it will still have resources reserved for the user even though they can never come back because the cookie was discarded in the client.

This setting is safer for the user because there is less chance that someone can come along and restart the session using same session cookie - if you tell the user to close the tab or browser when they have finished.

That said, there are some tricks that you can pull with javascript to try and catch the user closing the tab (as is implemented sometimes where a site will warn you if you try to navigate away but have unsaved changes). This could be used to fire off a 'bye' message to the server so that the server can clean up. This puts a dependency on javascript though - it would not work if js is disabled, and it also fires if the user just follows a link and then comes back again - their session on the server might be closed.

http://stackoverflow.com/questions/3888902/javascript-detect-browser-close-tab-close-browser

I hope this helps. Please understand that expire_on_close does absolutely nothing at the server, it just affects what the session cookie looks like.

You can see this in the developer tools in your browser if you inspect cookies.

7 likes
jekinney's avatar

Banking sites etc use a JavaScript timer to alert the user your session is timed out. I bet if you closed the browser or tab and opened it up right away you probably will still be logged in.

Generally they reset the expiration time on every request and restart the timer. Possibly use some type of socket/persistent connection too but that can be a security loop hole if not done right on a public computer.

@Snapey perfect post!

jlrdw's avatar

@jekinney and @Snapey I just signed into paypal, after signin copied the url. I closed the browser, reopened browser pasted url but was redirected to the login page. I then tried same thing but typed paypal.com and FF was set to keep history and cookies. So what is the technique used to accomplish this? I haven't put much thought to it before, as I tell users to sign out. But I'd like to know how paypal did it. Oh and there was a cookie stored from paypal. I thought laravel used file session for this. Does a cookie get set as well? This is another thing I would love to learn.
EDIT: I tried it with https://laracasts.com/discuss but I was still logged in. So let's figure out how paypal does it. Maybe @TaylorOtwell could use the technique in laravel.
EDIT2: I tried same thing with a site I did using ver 2.2 of https://github.com/nova-framework/framework
But I was sent to login page. The only thing I can think of is I use

session_regenerate_id(true);

In the admin controller, but that is in the login section, I don't think that would do it. I always run that just prior to a login.

jlrdw's avatar

@3ejoueur @jekinney @Snapey I see how I got it working, just never thought much of it, same thing would work in laravel. In every controller method where a login is required I have this:

$this->chklog();

At bottom of every controller I have this:

public function chklog()
    {
        if (Session::get('loggin') == false) {
            Url::redirect('admin');
        }
    }

Could probably put this as a helper, but just setting a session like this some how closing the browser and re-opening the value 'logged' is false. I picked up the code snipplet from somewhere, but don't remember where.

1 like
jekinney's avatar

Nice!!! @jlrdw. Like you I haven't hit this requirement yet so never dug very deep into it. Your research and testing is great so far. Like using auth I don't see any huge performance issue by looking. I'ld try to squeeze it in a middleware for global use? If not logged in via session check redirect to home page?

jlrdw's avatar

I just hope it helps the OP. I kinda have a confession to make even in laravel, I only use it as a mvc shell, I write my own Authentication etc using techniques from OWASP. I just like being in control. For a real simple site where maybe only one or two people have access to login then I use the built-in Authentication.

1 like
Snapey's avatar

@jlrdw I'm not sure you quite get it. If the cookie is set to be for the session only then when you close and reopen the browser, and visit the URL you had before, you will generate a new session so any session variable that was used before will still be present in the system but in your earlier session, and not the one you have now. Therefore any page that requires you to be logged in will send you to the login page.

Your old session will still persist but you will not be able to connect to it.

but just setting a session like this some how closing the browser and re-opening the value 'logged' is false. I picked up the code snipplet from somewhere, but don't remember where.

I hope this is clearer now, the value 'logged' is only false because it does not exist in your new session.

BTW I have noticed (in proving my theory) that Firefox (and Chrome and Safari) only discards the session cookie if you actually close the application. If you are on a mac and close the window then the browser is still running (has a dot underneath), and you can just open the window again, paste in the old URL and carry on.

2 likes
jekinney's avatar

@snapey very true on Mac, forgot about that.

@jlrdw I'm very close to the same, though I use a lot of what Laravel offers I don't use any boiler plate either. On a new install delete auth stuff, user model and welcome page ASAP. Start from bare bones so to speak.

jlrdw's avatar

@Snapey and @jekinney if either of you happen to know someone with a Mac and a PayPal account could you have them try what I tried. This thing has my curiosity up now because there has to be a way to be completely signed out and no chance of someone else getting back on.
I mean I am not having any kind of issue myself it just got intriguing is all.

jekinney's avatar

@jlrdw

Just did, paypal opened right where I left off in the history tab and going to paypal site by typing in url. When I made sure to quit chrome (no dot under it on my wow bar thing) it redirected me to login.

jlrdw's avatar

I guess the bottom line if someone is using certain browsers or a Mac tell them the following: follow these 3 rules:

  • logout
  • logout
  • logout
Snapey's avatar

@jlrdw yep same here. You have to actually quit the browser for the login page to be shown. You can copy the URL from a logged in session, close all windows, open the browser again, paste in the url and carry on where you were before.

1 like
Zile's avatar

@jlrdw OP took your advice and logout, and never managed to login again :)

1 like

Please or to participate in this conversation.