inertiajs / inertia-laravel

The Laravel adapter for Inertia.js.
https://inertiajs.com
MIT License
2.03k stars 227 forks source link

Laravel/VueJs XSRF/CSRF token rename is not working correctly using the useForm() functionality. #544

Closed michaelbeers closed 10 months ago

michaelbeers commented 1 year ago

In the current infrastructure of our servers i need to have two different csrf cookies. Serverside everything is working correctly but InertiaJS is not automatically using the BUSINESS-XSRF-TOKEN cookie name as configured in axios. Is this a bug or am I doing something wrong?

Environment:

VerifyCsrfToken middleware:

<?php

namespace App\Http\Middleware;

use Illuminate\Contracts\Encryption\DecryptException;
use Illuminate\Cookie\CookieValuePrefix;
use Illuminate\Cookie\Middleware\EncryptCookies;
use Illuminate\Foundation\Http\Middleware\VerifyCsrfToken as Middleware;
use Symfony\Component\HttpFoundation\Cookie;

class VerifyCsrfToken extends Middleware
{
    const TOKEN_NAME = 'BUSINESS-XSRF-TOKEN';

    protected $except = [

    ];

    protected function getTokenFromRequest($request)
    {
        $token = $request->input('_token') ?: $request->header('X-CSRF-TOKEN');

        ray($token, $request->headers);

        if (! $token && $header = $request->header('X-'.self::TOKEN_NAME)) {
            try {
                $token = CookieValuePrefix::remove($this->encrypter->decrypt($header, static::serialized()));
            } catch (DecryptException) {
                $token = '';
            }
        }

        return $token;
    }

    protected function newCookie($request, $config): Cookie
    {
        return new Cookie(
            self::TOKEN_NAME,
            $request->session()->token(),
            $this->availableAt(60 * $config['lifetime']),
            $config['path'],
            $config['domain'],
            $config['secure'],
            false,
            false,
            $config['same_site'] ?? null
        );
    }

    public static function serialized(): bool
    {
        return EncryptCookies::serialized(self::TOKEN_NAME);
    }
}

bootstrap.js

/**
 * We'll load the axios HTTP library which allows us to easily issue requests
 * to our Laravel back-end. This library automatically handles sending the
 * CSRF token as a header based on the value of the "XSRF" token cookie.
 */
import axios from "axios";

// Check the VerifyCsrfToken.php file for the correct token.
const XSRF_NAME = 'BUSINESS-XSRF-TOKEN';

window.axios = axios;

window.axios.defaults.headers.common["X-Requested-With"] = "XMLHttpRequest";
window.axios.default.xsrfCookieName = XSRF_NAME;
window.axios.default.xsrfHeaderName = "X-" + XSRF_NAME;
jessarcher commented 1 year ago

Hey there, thanks for reporting this issue.

We'll need more info and/or code to debug this further. Can you please create a repository with the command below, commit the code that reproduces the issue as one separate commit on the main/master branch and share the repository here?

Please make sure that you have the latest version of the Laravel installer in order to run this command. Please also make sure you have both Git & the GitHub CLI tool properly set up.

laravel new bug-report --github="--public"

Do not amend and create a separate commit with your custom changes. After you've posted the repository, we'll try to reproduce the issue.

Thanks!

reinink commented 10 months ago

Hey! So I'm not 100% what's up here, but is the issue that you're doing default and not defaults here?

window.axios.defaults.headers.common["X-Requested-With"] = "XMLHttpRequest";
window.axios.default.xsrfCookieName = XSRF_NAME;
window.axios.default.xsrfHeaderName = "X-" + XSRF_NAME;

See here: https://axios-http.com/docs/config_defaults

The other thing to double check is to make sure that that you don't have two different versions of axios installed — which can happen if you have it explicitly installed on your project but are using a different version than what Inertia uses.

But really there isn't anything in the Inertia JavaScript library or in this Laravel adapter that do anything with CSRF tokens, we rely on Laravel and axios' handling of this, so I don't think the problem exists on our end. You can read more about that here:

https://inertiajs.com/csrf-protection

Hope that helps!