If you want a dynamic behavior, you need to work with Livewire or VueJS and events.
Auto redirect to login page when auth session expires
How can I auto-redirect a user to the login page when their authentication expires? Currently, if the session expires, they are only redirected back to the login page if they refresh their screen.
The browser has no idea that it has been logged out, so you will need to have some Javascript that sends a request to the backend after a certain time to check. But be aware that every time you send a request, you will extend the session
Redirect with a javascript timer equal to the session life time
https://www.encodedna.com/javascript/redirect-page-after-a-delay-using-javascript.htm
@sr57 an over complicated solution. All that is needed is this in the header
<meta http-equiv="refresh" content="{{ config('session.lifetime') * 60 }}; {{ route('timeout', ['url' =>urlencode(url()->current())]) }}" />
The 'timeout' route is just a view that says 'sorry your session expired' and has a button to return to the previous page which was passed to it as a parameter.
This approach does not work for SPAs that don't refresh the whole page
@Snapey How does this work ? The route is in a meta tag, does it mean that the code will retrieve this route from the meta tag ?
suppose session lifetime is 120 minutes. You load this page and the meta refresh is also set to 120. If you navigate pages then the page life never reaches 120 minutes and this meta tag has no effect. If you do leave your browser on this page for 2 hours then it redirects to the timeout route.
You can then handle this however you require - such as showing a message. The parameter passed to the timeout route is the page you came from so that you can offer a 'return to last page' button
There are complications for pages that are spa or use livewire since the page refresh does not know about the content being swapped out. Also, you may be working in another tab when this one expires, so on the timeout route, don't just assume that the user is logged out.
Here is a solution for users using Inertia Vue with laravel:
# HandleInertiaRequests.php middleware:
public function share(Request $request): array
{
return [
...parent::share($request),
'auth' => [
'session' => [
'expires' => now()->addMinutes(config('session.lifetime'))->setTimezone('Europe/London')->toDateTimeString(),
],
],
];
}
// useSessionCheck composable:
import type { BasePageProps } from '@/types'
import { toast } from '@/components/ui/toast'
import { router } from '@inertiajs/vue3'
import { useDocumentVisibility } from '@vueuse/core'
import { watch } from 'vue'
/*
* If the user returns to the tab after a period of inactivity,
* check if the session has expired. If so, reload page
* (which will redirect to login page with intended
* url stored in session).
*/
export function useSessionCheck(props: BasePageProps) {
const expires = props.auth.session.expires
const expiresDate = new Date(expires)
const visibility = useDocumentVisibility()
watch(visibility, (visible) => {
if (visible === 'visible') {
const now = new Date()
if (expiresDate < now) {
toast({ title: 'Session expired', description: 'Please login again' })
router.reload()
}
}
})
}
// AuthenticatedLayout.vue
const props = defineProps<BasePageProps>()
useSessionCheck(props)
# .env
SESSION_LIFETIME=2
To test it out, I simply reduced my session lifetime to 2 mins, left the tab and returned 3 mins later, to be redirected to the login page with a friendly toast.
Please or to participate in this conversation.