Learn how CSRF Tokens Work in Laravel. Our Laravel Support team is here to help you with your questions and concerns.
How CSRF Tokens Work in Laravel
Cross-Site Request Forgery (CSRF) is a type of attack where a user is tricked into making unintended requests to a web application where they are already authenticated. This type of attack exploits the trust a web application has in the user’s browser.
Typically, web servers accept requests from any client as long as the requested page exists. However, certain pages require authentication.
In a CSRF attack, the attacker tricks an authenticated user into interacting with a malicious script or page from another site. The malicious request is sent to our server, which processes it because it assumes the request is legitimate.
An Overview:
- Protect Our Laravel App with CSRF Tokens
- Create a Laravel Application
- Set Up the User Model
- Database Migration
- Create the SendMoney Controller
- Create the Send Money Form
- Implement CSRF Protection
- Custom CSRF Token Error Handling
Protect Our Laravel App with CSRF Tokens
Laravel has built-in protection against CSRF attacks using tokens. These tokens are randomly generated strings attached to forms when created. The server checks for a CSRF token in POST requests, and if the token matches the one generated by Laravel, the form is processed. Otherwise, the request is denied.
The CSRF token is unique to each request and cannot be reused, providing additional security.
Create a Laravel Application
To demonstrate CSRF protection, let’s build a sample Laravel application that allows authenticated users to send money to friends.
- First, create a new Laravel project:
$ laravel new money-sender
- Then, set up authentication using Laravel’s built-in scaffolding:
$ php artisan make:auth
This command generates all the necessary files for user authentication, such as the signup, login, and dashboard pages.
Set Up the User Model
Laravel includes a User model by default. Let’s update it to include methods for charging and granting money to users:
namespace App;
use Illuminate\Notifications\Notifiable;
use Illuminate\Foundation\Auth\User as Authenticatable;
class User extends Authenticatable
{
use Notifiable;
protected $hidden = ['password', 'remember_token'];
protected $fillable = ['name', 'email', 'password', 'balance'];
public function charge(int $amount)
{
return $this->update(['balance' => $this->balance - $amount]);
}
public function grant(int $amount)
{
return $this->update(['balance' => $this->balance + $amount]);
}
}
Database Migration
Migrations in Laravel lets us track database changes. Let’s update the default user migration to include a `balance` field:
public function up()
{
Schema::create('users', function (Blueprint $table) {
$table->increments('id');
$table->string('name');
$table->string('email')->unique();
$table->string('password');
$table->integer('balance')->default(5000);
$table->rememberToken();
$table->timestamps();
});
}
Now, connect the application to an SQLite database by updating the `.env` file:
DB_CONNECTION=sqlite
DB_DATABASE=/full/path/to/database.sqlite
Then, create an empty `database.sqlite` file in the `database/` directory, and run the migration:
$ php artisan migrate
Create the SendMoney Controller
Next, create a controller to handle the money transfer:
$ php artisan make:controller SendMoneyController
Then, update the controller to process money transfers between users:
namespace App\Http\Controllers;
use App\User;
use Illuminate\Http\Request;
class SendMoneyController extends Controller
{
public function __construct()
{
$this->middleware('auth');
}
public function send(Request $request)
{
$data = $request->validate([
'email' => 'required|email',
'amount' => 'required|numeric'
]);
$sender = auth()->user();
$recipient = User::where('email', $data['email'])->first();
$sender->charge($data['amount']);
$recipient->grant($data['amount']);
return redirect()->action('HomeController@index')
->withStatus("${$data['amount']} sent to {$recipient->name}");
}
}
Create the Send Money Form
Then, create the form in the `home.blade.php` file:
@extends('layouts.app')
@section('content')
<div class="container">
<div class="row justify-content-center">
<div class="col-md-8">
<div class="card">
<div class="card-header">Dashboard</div>
div class="card-body">
@if (session('status'))
<div class="alert alert-success">
{{ session('status') }}
</div>
@endif
<p>Wallet Balance: ${{ $user->balance }}</p>
<form action="{{ url('/sendmoney') }}" method="post">
@csrf
<div class="form-group row">
<
Implement CSRF Protection
Laravel automatically includes CSRF protection. If a form is submitted without a CSRF token, the request will be rejected. Also, the `@csrf` directive in the form ensures that a valid CSRF token is included with the request:
<form action="{{ url('/sendmoney') }}" method="post">
@csrf
<!-- form fields -->
</form>
Hence, when the form is submitted, Laravel’s `VerifyCsrfToken` middleware checks for the token. So, if it’s missing or invalid, the request will be rejected.
Custom CSRF Token Error Handling
We can customize the error message returned when a CSRF token is invalid by updating the `render` method in `app/Exceptions/Handler.php`:
public function render($request, Exception $exception)
{
if ($exception instanceof TokenMismatchException) {
return response()->view('errors.401', ['error' => 'Page expired, go back and try again'], 401);
}
return parent::render($request, $exception);
}
Then, create a custom error view `401.blade.php` to display this message:
@extends('layouts.app')
@section('content')
<div class="container">
<div class="row justify-content-center">
<div class="col-md-8">
<div class="card">
<div class="card-header">Error</div>
<div class="card-body">
<div class="alert alert-danger">{{ $error }}</div>
</div>
</div>
</div>
</div>
</div>
@endsection
Hence, our Laravel application is well-protected from CSRF attacks, and if the CSRF token is missing, users will see a more user-friendly error page.
[Need assistance with a different issue? Our team is available 24/7.]
Conclusion
HAProxy is a robust tool for managing and routing traffic in complex architectures. By leveraging frontends and backends, dynamic reconfiguration with map files, and real-time management via the Runtime API, HAProxy becomes a powerful solution for scaling applications, ensuring high availability, and optimizing performance.
In brief, our Support Experts demonstrated how CSRF Tokens Work in Laravel.
0 Comments