1

I have have a web app which is waiting for users on a laptop in kiosk mode. Sometimes, registration fails and users get an error screen - I think it's 419 Session Expired.

So I assume two hours after the login screen loads, the session expires (I kept the default of 120 minutes in config/session.php) and Laravel does not accept any request from that page.

How should I deal with this? I know how to make a page reload every 110 minutes or so using JS, but then I'd have to check the registration form is being filled out at this moment. This does not feel like a clean solution to me.

Is there any alternative, such as a mechanism to make Laravel less strict when a request comes from the register or login pages?

Pida
  • 928
  • 9
  • 32
  • There are a couple of interesting solutions/discussions on these links, in case you haven't seen them: https://stackoverflow.com/questions/49677248/redirect-automatically-when-user-session-expires-in-laravel-5-5 https://gist.github.com/edomaru/061caa8dd596edf928cc9153fbb8ef62 https://stackoverflow.com/questions/41165900/php-how-to-detect-if-a-session-has-expired-automatically Might be helpful! – party-ring Jul 31 '19 at 11:02

3 Answers3

2

As mentioned, the simplest solution is usually to extend the session expiration time from the default of 2 hours (which is very short).

If longer sessions are not desirable, another option is to keep the session alive for as long as the browser page is open by using javascript.

Add a route in routes/web.php:

Route::post('/keep-alive', function () {
    return response()->json(['ok' => true]);
});

And then ping this route periodically with javascript:

setInterval(() => {
    axios.post('/keep-alive')
        .then(() => {})
        .catch(() => {})
}, 600000)

(I used axios to make the POST request because it's included with a default Laravel install, but you can use anything to make the request.)

Since the request passes through the web middleware group, the session middleware should be run and keep the session alive. If the browser page is closed, the computer is put to sleep, etc., then the session will still expire normally after the configured time has elapsed.

You can also check for session expiration responses from the javascript call and then refresh the page, prompt for credentials, or perform some other action if you detect that the session expired. This case is most likely to occur if the computer resumes operation from a sleeping state.

Travis Britz
  • 5,094
  • 2
  • 20
  • 35
  • I updated the example to use POST instead of GET. GET requests will still keep the session alive, but POST requests will allow you to detect a HTTP 419 response from javascript if the current session was expired when it made the request (instead of silently generating a new session cookie). – Travis Britz Jul 31 '19 at 13:34
1

You note yourself that you can change the session time in config/session.php. Is there a reason why you don't want to change that?

Alternatively, assuming that this is not an app that is accessible on the World Wide Web and is for Kiosk use only, you can exclude certain routes from requiring the CSRF token altogether;

Edit the **$except** property of the VerifyCsrfToken middleware;

protected $except = [
    'stripe/*',
    'http://example.com/foo/bar',
    'http://example.com/foo/*',
];

Information taken from the Laravel Documentation.

Lewis
  • 3,479
  • 25
  • 40
  • "assuming that this is not an app that is accessible on the World Wide Web" sounds like a *really* dangerous assumption to make about a PHP application. – Travis Britz Jul 31 '19 at 11:28
  • @TravisBritz That's based on what the OP says in their question. – Lewis Jul 31 '19 at 11:29
  • @Lewis The app is accessible on the WWW. It's just that right now we use one or more of our own laptops in kiosk mode and have people use the app. That's why I realized registration using a form that had been opened three hours before does not work. As my problem only applies to a single page, I'd rather not set session lifetime too a much higher value as a precaution. – Pida Jul 31 '19 at 12:57
1

I think you might want to take a look at this package:

laravel-caffein

Hope it helps :)

Pida
  • 928
  • 9
  • 32
Pedro X
  • 849
  • 5
  • 13
  • Thanks, I even heard about this before. For my case, I prefer Travis' solution as I only need this functionality on a single page. – Pida Jul 31 '19 at 12:59
  • I actually got this method from viewing the laravel-caffein source a few years ago, but for my cases decided it was actually less complex to roll my own and not worry about the dependency or config. – Travis Britz Aug 20 '19 at 21:34