7

I created an SPA with Laravel 5.6, Vue 2.5 and Laravel Passport which is working quite well. I really love Laravel and Vue as they make building SPAs with APIs very easy and a lot of fun.

After setting up Laravel Passport as described in the docs the login as well as calls to the API are working as expected based on the 'laravel_token' which is correctly returned and stored in the cookie.

However, my problem is that my users are using the app for a pretty long time, without reloading the page but only performing calls against the API with axios. Somehow Laravel does not refresh the 'laravel_token' (and the corresponding cookie) in API calls (it does so, when I call a 'web' route). Consequently, the 'laravel_token' expires t some point and the user needs to log in again.

How can I force Laravel to refresh the 'laravel_token' (and thereby prolong its validity) with every call of an API route from axios?

Any help is very much appreciated!

Matthias
  • 71
  • 2
  • Decide the length before the user has to sign in again, then if it expires thats hard cheese. For those who use the app more often then you should check the jwt expiry and decide on when to send a refresh token request. RTM: https://laravel.com/docs/5.6/passport#refreshing-tokens – Lawrence Cherone Mar 17 '18 at 21:28
  • Thanks for your quick answer. Can I also use this to refresh the 'laravel_token' which is the JWT version of the token? More general, my question was, if this really is necessary. As my users interact with the API during the lifetime of the token, my understanding is that it should be prolonged - anyway this does not happen automatically in API calls (but it does in web calls). – Matthias Mar 17 '18 at 22:41
  • Hi. Are you using Axios? If so, when trying to send requests to your api with an expired `laravel_token`, add an interceptor(https://github.com/axios/axios#interceptors) for all 401 response that sends an alert or something to the user that their session expired and they or the SPA needs to refresh the page again. – Kenth John Israel Sep 28 '18 at 07:11

2 Answers2

2

I solved a similar issues in the past by creating a simple route (in the web middleware group) to keep the session alive for as long as the browser tab is open.

In routes/web.php:

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

And then ping this route periodically with javascript:

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

I go into a little more detail here: https://stackoverflow.com/a/57290268/6038111

Travis Britz
  • 5,094
  • 2
  • 20
  • 35
0

Axios has a way to "intercept" / see if a call failed. Inside the error callback I am seeing if it was an unauthenticated error and simply reloading the page.

Admittedly, I would love to be able to write another Axios call inside the error caught block to grab another session token "laravel_token", but have yet to find a way to do it. Reloading the page will refresh the laravel_token though, so it solves my problem for now. ¯\_(ツ)_/¯

After-thought: I'm actually thinking you probably couldn't refresh the laravel_token through an Axios call because you'e already dropped the session. I'm guessing you have to do it this way.

// Refresh Laravel Session for Axios
window.axios.interceptors.response.use(
    function(response) {
        // Call was successful, don't do anything special.
        return response;
    },
    function(error) {
        if (error.response.status === 401) {

            // Reload the page to refresh the laravel_token cookie.
            location.reload();
        }

        // If the error is not related to being Unauthorized, reject the promise.
        return Promise.reject(error);
    }
);
fylzero
  • 460
  • 6
  • 18