Sanctum API: несоответствие токена 419 CSRF с laradock

Я создал проект в Laravel 11 с Laradock в мультипроекте и таким образом определил хост в файле хостов:

127.0.0.6 laravel.api.test

конфигурация/cors.php

return [
    'paths' => ['api/*', 'sanctum/csrf-cookie', 'auth/*'],

    'allowed_methods' => ['*'],

    'allowed_origins' => ['*'],

    'allowed_origins_patterns' => [],

    'allowed_headers' => ['*'],

    'exposed_headers' => [],

    'max_age' => 0,

    'supports_credentials' => true,
];

загрузочный файл/app.php:

return Application::configure(basePath: dirname(__DIR__))
    ->withRouting(
        web: __DIR__ . '/../routes/web.php',
        api: __DIR__ . '/../routes/api.php',
        commands: __DIR__ . '/../routes/console.php',
        health: '/up',
    )
    ->withMiddleware(function (Middleware $middleware) {
        $middleware->statefulApi();
    })
    ->withExceptions(function (Exceptions $exceptions) {
        //
    })->create();

маршруты/сеть:

Route::prefix('auth')->group(function () {
    Route::post('/login', LoginController::class);
});

.env:

SESSION_DRIVER=database
SESSION_LIFETIME=120
SESSION_ENCRYPT=false
SESSION_PATH=/
SESSION_DOMAIN=.api.test

SANCTUM_STATEFUL_DOMAINS=laravel.api.test

затем я вызываю этот маршрут в POST с помощью почтальона:

http://laravel.api.test/auth/login

в качестве параметров на этапе заголовка:

Accept:application/json
X-CSRF-TOKEN:{{xsrf-token}}

и в разделе Pre-request-script:

pm.sendRequest({
    url: "http://laravel.api.test/sanctum/csrf-cookie",
    method: "GET"
}, function (err, res, { cookies }) {
    if (!err) {
        console.info('xsrf-token', cookies.get('XSRF-TOKEN'))
        pm.globals.set('xsrf-token', cookies.get('XSRF-TOKEN'))
    }
})

Я получаю следующую ошибку 419:

{
    "message": "CSRF token mismatch.",
    "exception": "Symfony\\Component\\HttpKernel\\Exception\\HttpException",
    "file": "/var/www/laravel_api/vendor/laravel/framework/src/Illuminate/Foundation/Exceptions/Handler.php",
    "line": 633,
    "trace": [

ВОРОТ Почтальон

ПОЛУЧИТЕ http://laravel.api.test/sanctum/csrf-cookie 204 42 мс

xsrf-токен

eyJpdiI6IlZDSis1d2kyR0lXWWdWc2VEeEV3MGc9PSIsInZhbHVlIjoiZ3htNlBaYXlwL2d0dlBITXpGZVp3ejN4V1NGYm5iK21EWGI1dFZObEZlNmhRZ1UrWXVLUlk0SmhPckZ4YUdJUjZuK3hBcVl4YkpDZnNKMisyRmQyYkhITlBVblhjdWxpdU92aFc4NU5MOTVYSWIzTE1wU3dOVzFCTXJMMGt3UDEiLCJtYWMiOiI0NWNiOTY4MWRhZjdjYmNhNjQyMjY5MGQzMGQ5MzYxZWFjNjljODIzYmQ0NDUwNzUwNjQ1MmEwNzI0NGI3ZDcyIiwidGFnIjoiIn0=

ПОСТ http://laravel.api.test/auth/login

419
75 ms
Network
Request Headers
Accept: application/json
X-CSRF-TOKEN: eyJpdiI6IlZDSis1d2kyR0lXWWdWc2VEeEV3MGc9PSIsInZhbHVlIjoiZ3htNlBaYXlwL2d0dlBITXpGZVp3ejN4V1NGYm5iK21EWGI1dFZObEZlNmhRZ1UrWXVLUlk0SmhPckZ4YUdJUjZuK3hBcVl4YkpDZnNKMisyRmQyYkhITlBVblhjdWxpdU92aFc4NU5MOTVYSWIzTE1wU3dOVzFCTXJMMGt3UDEiLCJtYWMiOiI0NWNiOTY4MWRhZjdjYmNhNjQyMjY5MGQzMGQ5MzYxZWFjNjljODIzYmQ0NDUwNzUwNjQ1MmEwNzI0NGI3ZDcyIiwidGFnIjoiIn0=
Content-Type: text/plain
User-Agent: PostmanRuntime/7.37.0
Postman-Token: 7ff581ea-e9b2-4b69-8423-a7c9ff349e83
Host: laravel.api.test
Accept-Encoding: gzip, deflate, br
Connection: keep-alive
Content-Length: 60
Cookie: XSRF-TOKEN=eyJpdiI6IlZDSis1d2kyR0lXWWdWc2VEeEV3MGc9PSIsInZhbHVlIjoiZ3htNlBaYXlwL2d0dlBITXpGZVp3ejN4V1NGYm5iK21EWGI1dFZObEZlNmhRZ1UrWXVLUlk0SmhPckZ4YUdJUjZuK3hBcVl4YkpDZnNKMisyRmQyYkhITlBVblhjdWxpdU92aFc4NU5MOTVYSWIzTE1wU3dOVzFCTXJMMGt3UDEiLCJtYWMiOiI0NWNiOTY4MWRhZjdjYmNhNjQyMjY5MGQzMGQ5MzYxZWFjNjljODIzYmQ0NDUwNzUwNjQ1MmEwNzI0NGI3ZDcyIiwidGFnIjoiIn0%3D; laravel_session=eyJpdiI6ImRyUGh2ZklLUFhYbCtwTnpqSWZ0SHc9PSIsInZhbHVlIjoiQ1BJbGloZGhPYmlKTlpTSHIxZjNTQVhEQkpER210NWlhdlpwVUN3OFJkTkJ5UmdKWVpZOVNybE9uV2NaTWtiNGZCZnEzanpRNi81T08zOE43ME9pTnhhMmJScEhDc1hXeGc0emJnQUl2VjgvZXd3a0NneU9xZm9nYTljblllb0YiLCJtYWMiOiIwMDVmYzM0ODcwZmZlMTU3OWJhYTJjNjhlOTAxNzE4OTFlMDI4OGQ1Y2ZhNWUxZWJhNTBjY2E2Y2RlOWI2ODEzIiwidGFnIjoiIn0%3D; tC8zpXwRJnmAZKHQkeY1sldxapFyUQ545wEeOmLq=eyJpdiI6IjNadzNiT1RHVXF3WlUwR3Z6UUJaTnc9PSIsInZhbHVlIjoiTEpLeXg0eDJ6MkFLMGhXN0t6Vy9sT2FPZGtmTkR5MFpKYXE2MlNxdlZWVjc5dGt3enk5Y21FOUIvNjIrZUxUcUlmZHVFYkEyNDdPLzBKWWlRYnVtMUFXekhLMWF2SnlxSDNwWHFhbVdMdFRZb1haSXdxYlpFQ21jZUJsT2hKb2xXZGNRTVVpYWUxZU5aYlJLUldnOU8xMkd4NHdQaE0xVkxWbGxhQTh0SlUrNHJSWlNadHJmTTBIbnA5cTZvSE45anhNaXFaeEh1SkVqUnVsMS9uVHhCaGNrR3E1M2NGdG9rNjJzLzFrM21TKzFYRlY3eGd6dEswZHhoNjUxNXhOTVozMDNoUmhXSkd6cmFONkx5NjJROU44bzc0Mk03YTRCWEFRaEZGWDdtOHQ2SnhLd3NsWHFTaUIzSzk2VkpTSTViNXVCSHVhVVJSdVc2SDBrSEVFZER4RDFzak1sZFpRVHpyeVdZUzlEZHNFRW0wVk4xUXFwN2F1bVRZZjhhWUw1VWhXTEszMjVwMlE2eXpDbTRIT3ptZHVuUWRYYVg1eDBGL0RVelFvSDFjN0REcTJHcnZWdDFrTjcycmhwTnJRRDM5UWlTZUJmS2ZtenJpU3BXVDFxWU84bXRzOVQ0TUdoMUxSdmtoRnhZOHF1Q1pvSzlqQTNGT3hERXdkbU5menY5VGlXcXgyZzJ2OTFxL3I3VCtuMHRoSkllZFdBa1Q5cjhPdnQ2aSsxNVljTEUwNWt5eDNKL1Bpb1NZMEZwWnFHS25NR05OOUVjcm40Wi9xUTY3N3Z0bk5RRjF1RFdOdXVUOHBhZENxRDZSM0JNSHcyRVpGMjAxVjN2K215OFR5UHM2YjNPRjNQRFR0MFVEYlFnQm5HZWVBMFpRUXpQVElyYjVOdkEwLzBQWEtkS1NUTUI3MmYxSm5LSVBsaW9rUTVFNlRpVlprd1BCK3N5ejhqeGd6UHBhc1M5Znh5TGp2N2Z6Z25yZmtLcWF0b09SYzhRWklmVlkzcEJQWGFUUkxlT20wS2NMUVVsTldUVm1PWnNidXZjclJ4aWJpM3JEelBqaFh1REVVWGIzN0k1NTRBdnhlS1NYZDE0VW5oTW1IQklCYWF6R0pOakhhSEZOVmJudzF3ZlB6Z0ZMNWlTQ0dEMnJ5OXRrZ3dRT0k9IiwibWFjIjoiNDA3MzhlMzM1ZjZkMGI5MTUwZGE5OTc0MDQ5NDlkZGRmNmRmZTg3ODU2ZWFhZjBmZDIzMzEwYzk4NTA0YzFmOCIsInRhZyI6IiJ9
Request Body
Response Headers
Server: nginx
Content-Type: application/json
Transfer-Encoding: chunked
Connection: keep-alive
X-Powered-By: PHP/8.3.4
Cache-Control: no-cache, private
Date: Thu, 04 Apr 2024 10:36:55 GMT
Vary: Origin
Set-Cookie: laravel_session=eyJpdiI6ImVodzRoUHFZN25qWTZTU0h3QmRPanc9PSIsInZhbHVlIjoieThJUnE5L1lkRFdBK3NQSTlubzJOUFVSVjA5V2RvTkVtSnBXL25Md3ZWWEJ4Q2xRT3RuTXhqMGhaamdjK1JqL3N5SGV5MDdkMzZURW85SUkxbW1GUS9mdTdoRGllMTJVeGN6cVk3bTBiSlA4dUpYQUtZeDBFWXg4cmtLeEdKL3EiLCJtYWMiOiI2MTRmYTdhMTQ3MmFmNzhkODczYzZkNjhiMGE2NGE5YjBhYWE2NDkzZGMyZTliZDk1OTI0MDVkZWE1YTUxYTgzIiwidGFnIjoiIn0%3D; expires=Thu, 04 Apr 2024 12:36:55 GMT; Max-Age=7200; path=/; domain=.api.test; httponly; samesite=lax
Set-Cookie: tC8zpXwRJnmAZKHQkeY1sldxapFyUQ545wEeOmLq=eyJpdiI6Imx2eTBWTW9HaHBiWFRhRHpuODJRR1E9PSIsInZhbHVlIjoiZzVCSGpqbVpzVmpXVjVuMnlRL29jMEx4dURiUElaVmc2U3BYaEkyUjJvZ29oY056NTNxd2NtQmdQakxvOW93VlRXTTM1Vks4S2pmdGNaWlk5RWw2NWFUL3RsK1hWekJkZHV3YW9KVlZZbHkrQ1BqZmlQM0ZnMHp2emwvZCtEcVcwd2QzNVNXWHRndHpCZkdYUFJjWG4zUTl3bDNMajcvVElPdjFXWEFQMXVwbjlEcTNNSDR6ZEJ5QnY2NCtuYm5wTWhxZ1RXc0RZYWtVVE1yQmJUWDVwZktEdWdRclM4SjB2QXgzcGtpK2RFaVQzN2VnR1lVY055N0p1SDAxSGNGY09RY0RVUjNXallDOGFFVTU0aktxcWdhcHZMZThyTXJaU2xYZHV1RjZFVkwxVFhmMjR3T0ZkQ1FqNDA3K1lmQUh0VnZHNGkyNG1SRTFhM3g0akIvNFFKR0pIQUpobHNXWVhrdjhnZHl4SXpTMFBUYVRMaEpqR09Eakl1UzNEdE8weG1nRkFLRjM0RkFQMGUzOXI4UXRBMGoxRW9uQms0cWg4WFNGZnZWakZwckJpNG85Y3hKeWhoc3h3S1ltb3h6VzNPaHpCUlFkVDdxeDVOR2h1VnF0M2Z3RU1kVytoU1BIT2RrR3lOS2NLdUtRT1IyV0N1UUZlWndka0hXNm5xZThDY3dwZE9jb0phWWtwK0cwa05sWXhMbmxZK0pIM21BZk4rUUQzZjdUWTJ6cnJMdnRoeXcyQWU3Y0Z5TE5mSy8xWk41TWROTmZ1SktEMDhQM1paZGF4Wnk0ZUtWU2pDcG9KN08xVjZLNWw2NENVc0Q2ajdoVnd3Qks0UlZoT2R1VjNzeWszYmdYYjYyaEhFR3M1YjJFa3RtTFQ2d2JPbFZENG9FSTBZTjQ3cTEwNDJVKzJsQ2thTzI0RDkxZTJLU2xiZVBqbWJROVJJUm9FUE1OajBkNmxGaFFMUHBYQy9vS1Avd3lJUnVaYnVxWkJsQ0JRUFN0amRpNmVqMkZITGlDZjN3WGpwMU1NelNDaWhiUDc3c0tSSVBaV0tTbjBRbEFWdWttRklBQ2oyNkxlU1ZNbm02VTdqZTVDaTRTS1Z0SWZqbjI3NSsvYk40aUhpYnBwbjY2V01GMVM5NHBjZ2hiUkhFMld3TUQ4OVU9IiwibWFjIjoiZmU4NDQ4YzBiYTJmNmJjNGUzY2JjZTFjZWU3YWVhZjBlYTMzNDA1YWJhMzMyODViZTA4YjViMmU5OTJhYTBlMyIsInRhZyI6IiJ9; expires=Thu, 04 Apr 2024 12:36:55 GMT; Max-Age=7200; path=/; domain=.api.test; httponly; samesite=lax
SESSION_DOMAIN=.api.test <<== Я бы заменил это на laravel.api.test, давайте шить, если это поможет
UnderDog 04.04.2024 03:44

Я уже пробовал, но, к сожалению, не работает. Когда он проходит через промежуточное программное обеспечение VerifyCsrfToken, он терпит неудачу в методе tokensMatch hash_equals($request->session()->token(), $token) от false, это xsrf-токен, который я передаю ему

Gianmarco Gagliardi 04.04.2024 09:31

eyJpdiI6IjZTU0dpOTMrajArZDR3TXVvUSswaWc9PSIsInZhbHVlIjoieWNB‌​eGkyM2tOTUw1V1NrR3Zk‌​bTll NFQ2amxSTThkTE0xM2ozdmgyZkYybnB4dzVoYUhFZVU3QTloK2x2TkVCMHRO‌​RXMzSTNMMSs3d0QvNnNR‌​allvbk9LYVoxejNPVFVm‌​VXR6R2hwdjM5Um9Ldkxh‌​K3pRTklXS2poaUY2WDh5‌​bXkiLCJtYWMiOi IzNmI0NTZmY2I3NzI2Y2IwNmRhMWVhNmFjMjcwMTUzODg1NDZlNDZiM2YzMz‌​kzNDdkYzdlNjFlNWJmNz‌​hhYWQ0IiwidGFnIjoiIn‌​0

Gianmarco Gagliardi 04.04.2024 09:31
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
2
3
492
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Я решил это, изменив сценарий предварительного запроса:

  pm.sendRequest({
    url: "http://laravel.api.test/sanctum/csrf-cookie",
    method: "GET"
}, function (err, res, { cookies }) {
    if (!err) {
        const xsrfToken = cookies.has('XSRF-TOKEN') ? cookies.get('XSRF-TOKEN') : null;
        if (xsrfToken) {
            // Add X-XSRF-TOKEN to the header of the subsequent request
            console.info('xsrfToken', xsrfToken);
            pm.request.headers.add({ key: 'X-XSRF-TOKEN', value: xsrfToken });
        } else {
            console.error('XSRF-TOKEN not found in cookies');
        }
    } else {
        console.error('Error fetching CSRF token:', err);
    }
});

проблема заключалась в проблеме кодирования токена с почтальоном и бессонницей, поэтому мне удалось ее решить.

Убедитесь, что токен CSRF правильно обновляется и включен в запрос POST. Если проблема не устранена, вам может потребоваться дополнительно проверить конфигурацию среды Laravel, чтобы убедиться, что управление токенами CSRF настроено правильно.

Другие вопросы по теме