Last active
November 23, 2023 11:50
-
-
Save tanthammar/02c615e73022c44dda6533ed9416ac29 to your computer and use it in GitHub Desktop.
Laravel Livewire Turbolinks Blade component to keep session alive
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{{-- You do not need to add this component if you are using the permanent option in the head component --}} | |
<script> | |
if (!window.sessionTimerPermanent && window.Livewire) { | |
window.livewire.hook('afterDomUpdate', startSessionTimer) | |
} | |
// if you are on livewire > 1.3.1 and want to avoid the default error alert | |
// https://github.com/livewire/livewire/pull/1146 | |
window.livewire.onError(statusCode => { | |
if (statusCode === 419) { | |
return | |
} | |
}) | |
*/ | |
</script> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@props([ 'permanent' => false, 'expiresIn' => 10 ]) | |
@php | |
$session = config('session.lifetime'); | |
$message = trans('messages.session_expiration_warning', ['expires' => $expiresIn]); //example: 'Your session will expire in :expires minutes, due to inactivity! Click OK to avoid being logged out.' | |
@endphp | |
<script> | |
let sessionTimer = null | |
function clearTimer() { | |
clearTimeout(sessionTimer) | |
sessionTimer = null | |
} | |
function handleSessionWarning() { | |
alert('{{ $message }}') | |
checkAuth() // remove if you want to run this automatically on window.focus after clicking the alert, see end of script. | |
} | |
function startSessionTimer() { | |
clearTimer() | |
sessionTimer = setTimeout(handleSessionWarning, 1000 * 60 * {{ $session - $expiresIn }}) | |
} | |
function checkAuth() { | |
if (document.hasFocus()) { //remove this if you want to keep the session alive even if the window is out of focus | |
// console.info('fetching') | |
fetch('/check-auth') | |
.then(response => response.text()) | |
.then(auth => { | |
if (auth !== 'true') { | |
window.location.href = "{{ route('login') }}" | |
} | |
@if(!$permanent) | |
startSessionTimer() | |
@endif | |
}) | |
} | |
} | |
@if($permanent) | |
window.sessionTimerPermanent = true | |
setInterval(checkAuth, 1000 * 60 * {{ $session - 2 }}) | |
@else | |
window.sessionTimerPermanent = false | |
// document.addEventListener('turbolinks:load', startSessionTimer) //uncomment if you use turbolinks | |
document.addEventListener('DOMContentLoaded', startSessionTimer) //remove if you use tubolinks | |
@endif | |
// window.addEventListener('focus', checkAuth) //uncomment this if you remove checkAuth() above, observe that this makes an extra request on each window.focus | |
</script> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Route::get('check-auth', fn () => response(auth()->check() ? 'true' : 'false'))->middleware('auth'); |
UPDATE: Livewire v1.3.1
has error handling.
If you do not wish to use the timer and simply want to redirect the user to the login page you can ignore all the code above and instead add this to your main layout.
window.livewire.onError(statusCode => {
if (statusCode === 419) {
window.location.href = "{{ route('login') }}"
}
})
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
config('session.lifetime')
for the session timerUse
In the head
After livewire scripts, not needed if
permanent=true
, or the page doesn't use Turbolinks/Livewire