add proper error handling for expired CSRF Token

This commit is contained in:
Gregor Vostrak
2024-05-02 17:25:57 +02:00
parent 271d804091
commit 1c8d895c1e
4 changed files with 39 additions and 1 deletions

View File

@@ -5,6 +5,8 @@ declare(strict_types=1);
namespace App\Exceptions; namespace App\Exceptions;
use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler; use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler;
use Illuminate\Http\RedirectResponse;
use Symfony\Component\HttpFoundation\Response;
use Throwable; use Throwable;
class Handler extends ExceptionHandler class Handler extends ExceptionHandler
@@ -29,4 +31,17 @@ class Handler extends ExceptionHandler
// //
}); });
} }
public function render($request, Throwable $e): Response|RedirectResponse
{
$response = parent::render($request, $e);
if ($response->getStatusCode() === 419) {
return back()->with([
'message' => 'The page expired, please try again.',
]);
}
return $response;
}
} }

View File

@@ -40,6 +40,9 @@ class HandleInertiaRequests extends Middleware
{ {
return array_merge(parent::share($request), [ return array_merge(parent::share($request), [
'has_billing_extension' => Module::has('Billing'), 'has_billing_extension' => Module::has('Billing'),
'flash' => [
'message' => fn () => $request->session()->get('message'),
],
]); ]);
} }
} }

View File

@@ -1,5 +1,5 @@
<script setup lang="ts"> <script setup lang="ts">
import { Head, Link, useForm } from '@inertiajs/vue3'; import { Head, Link, useForm, usePage } from '@inertiajs/vue3';
import AuthenticationCard from '@/Components/AuthenticationCard.vue'; import AuthenticationCard from '@/Components/AuthenticationCard.vue';
import AuthenticationCardLogo from '@/Components/AuthenticationCardLogo.vue'; import AuthenticationCardLogo from '@/Components/AuthenticationCardLogo.vue';
import InputError from '@/Components/InputError.vue'; import InputError from '@/Components/InputError.vue';
@@ -26,6 +26,12 @@ const submit = () => {
onFinish: () => form.reset('password'), onFinish: () => form.reset('password'),
}); });
}; };
const page = usePage<{
flash: {
message: string;
};
}>();
</script> </script>
<template> <template>
@@ -47,6 +53,11 @@ const submit = () => {
<div v-if="status" class="mb-4 font-medium text-sm text-green-400"> <div v-if="status" class="mb-4 font-medium text-sm text-green-400">
{{ status }} {{ status }}
</div> </div>
<div
v-if="page.props.flash?.message"
class="bg-red-400 text-black text-center w-full px-3 py-1 mb-4 rounded-lg">
{{ page.props.flash?.message }}
</div>
<form @submit.prevent="submit"> <form @submit.prevent="submit">
<div> <div>

View File

@@ -27,6 +27,9 @@ const page = usePage<{
jetstream: { jetstream: {
hasTermsAndPrivacyPolicyFeature: boolean; hasTermsAndPrivacyPolicyFeature: boolean;
}; };
flash: {
message: string;
};
}>(); }>();
</script> </script>
@@ -47,6 +50,12 @@ const page = usePage<{
</Link> </Link>
</template> </template>
<div
v-if="page.props.flash?.message"
class="bg-red-400 text-black text-center w-full px-3 py-1 mb-4 rounded-lg">
{{ page.props.flash?.message }}
</div>
<form @submit.prevent="submit"> <form @submit.prevent="submit">
<div> <div>
<InputLabel for="name" value="Name" /> <InputLabel for="name" value="Name" />