Sending POST Requests with CSRF Protection in Laravel 11 using JavaScript

Last update: 06-12-2024

When working with Laravel 11, it's not easy to find up to date information regarding how to send a POST request with CSRF protection using JavaScript's fetch API.

While adding @csrf to an HTML form is straightforward, sending a POST request directly from JavaScript requires a different approach. This guide will walk you through the process.

Introduction to CSRF Protection in Laravel

Laravel includes CSRF protection by default. Any request that modifies server state must include a CSRF token to ensure the request is legitimate. For form submissions, you can simply use @csrf in your Blade template. However, for AJAX requests or other non-form submissions, you need to manually include the CSRF token.

Including the CSRF Token in JavaScript Requests

The most straightforward way to include the CSRF token in a JavaScript request is to send it in the request body. This method eliminates the need to modify request headers extensively. Below is an example of how to do this.

Example Implementation

Let's start by setting up a simple Laravel route and view. We'll create a route to display our view and another to handle the POST request.

web.php


<?php

use Illuminate\Support\Facades\Route;
use Illuminate\Http\Request;

Route::get('/', function () {
    return view('welcome');
});

Route::post('/post-endpoint', function (Request $request) {
    \Log::info($request->all());
    return ['Received data' => $request->moreData];
});

Next, let's create the Blade template that will include our JavaScript code to send the POST request.

welcome.blade.php


<!DOCTYPE html>
<html>

<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>Laravel</title>
</head>

<body>
    <button id="post-btn">Send post request</button>
    <script>
        const submitButton = document.getElementById('post-btn');
        submitButton.onclick = function () {
            fetch('/post-endpoint', {
                headers: {
                    "Content-Type": "application/json",
                },
                method: "post",
                body: JSON.stringify({
                    _token: '{{ csrf_token() }}',
                    moreData: "Some additional data"
                })
            }).then(function (response) {
                return response.json()
            })
                .then(function (data) {
                    console.log(data);
                })
                .catch(function (error) {
                    console.log('error');
                })
        }
    </script>
</body>

</html>

Explanation

In the welcome.blade.php file, we have a button with an ID of post-btn. When this button is clicked, it triggers a JavaScript function that sends a POST request to the /post-endpoint URL. The request includes the CSRF token and additional data in the request body, formatted as JSON. We also set the Content-Type header to application/json to indicate that we are sending JSON data.

On the server side, the route defined in web.php logs the received data and returns a response containing part of the received data.

Conclusion

By following the above steps, you can easily send POST requests with CSRF protection using JavaScript in Laravel 11. Including the CSRF token in the request body is a simple and effective method to ensure your requests are secure.

7 Comments

Add a new comment: