Form Handling & CSRF Protection
Laravel requires CSRF tokens on all form submissions to prevent Cross-Site Request Forgery attacks. Blade's @csrf directive generates the hidden token field automatically. HTML forms only support GET and POST, so Laravel uses @method('PUT') or @method('DELETE') to spoof other HTTP methods — the framework reads the _method hidden field and routes the request correctly.
Form Examples
{{-- Create form --}}
<form method="POST" action="{{ route('posts.store') }}">
@csrf
<input name="title" value="{{ old('title') }}" />
<textarea name="body">{{ old('body') }}</textarea>
<button type="submit">Create Post</button>
</form>
{{-- Edit form (PUT method) --}}
<form method="POST" action="{{ route('posts.update', $post) }}">
@csrf
@method('PUT')
<input name="title" value="{{ old('title', $post->title) }}" />
<textarea name="body">{{ old('body', $post->body) }}</textarea>
<button type="submit">Update Post</button>
</form>
{{-- Delete form (DELETE method) --}}
<form method="POST" action="{{ route('posts.destroy', $post) }}">
@csrf
@method('DELETE')
<button type="submit" onclick="return confirm('Delete?')">Delete</button>
</form>
{{-- old() repopulates form after validation failure --}}How CSRF Protection Works
When a user loads a form, Laravel generates a unique CSRF token tied to their session and embeds it as a hidden field via @csrf. When the form is submitted, the VerifyCsrfToken middleware compares the submitted token to the session token. If they don't match (e.g., the request came from a malicious site), Laravel returns a 419 Token Mismatch error and rejects the request. This prevents attackers from tricking users into submitting forms they didn't intend to. The old() helper is equally important — when validation fails and the user is redirected back, old('title') repopulates the field so they don't have to retype everything. For edit forms, old('title', $post->title) shows the previous input if validation failed, or the model's current value on first load.
Never trust client input. CSP headers.
Industry Best Practices
- Always write tests for this functionality - it's the most reliable way to catch regressions when you refactor or update packages
- Follow the single responsibility principle: each class does one thing. If a method grows beyond 20 lines, consider extracting helper methods or moving logic to a service class
- Profile performance with Laravel Debugbar (composer require barryvdh/laravel-debugbar) during development - it shows query counts, memory usage, and request timeline
- Keep dependencies up to date: run composer audit regularly to check for security vulnerabilities in your package dependencies
- Document validation rules with comments explaining why - e.g., // max:5 because users complained about spam when unlimited
Tip
Tip
Practice Form Handling CSRF Protection in small, isolated examples before integrating into larger projects. Breaking concepts into small experiments builds genuine understanding faster than reading alone.
Practice Task
Note
Practice Task - (1) Write a working example of Form Handling CSRF Protection from scratch without looking at notes. (2) Modify it to handle an edge case (empty input, null value, or error state). (3) Share your solution in the Priygop community for feedback.
Quick Quiz
Common Mistake
Warning
A common mistake with Form Handling CSRF Protection is skipping edge case testing - empty inputs, null values, and unexpected data types. Always validate boundary conditions to write robust, production-ready laravel code.
Key Takeaways
- Laravel requires CSRF tokens on all form submissions to prevent Cross-Site Request Forgery attacks.
- Always write tests for this functionality - it's the most reliable way to catch regressions when you refactor or update packages
- Follow the single responsibility principle: each class does one thing. If a method grows beyond 20 lines, consider extracting helper methods or moving logic to a service class
- Profile performance with Laravel Debugbar (composer require barryvdh/laravel-debugbar) during development - it shows query counts, memory usage, and request timeline