Laravel «Несоответствие токенов CSRF» для POST с laravel-cors и axios - PullRequest
1 голос
/ 30 июня 2019

У меня домен_А, работающий Laravel 5.8 движок для возврата API на веб-маршрут . Он должен проверять происхождение, чтобы обслуживать только несколько доменов, включая domain_B.

Barryvdh / Laravel-CORS
Я установил barryvdh / laravel-cors с помощью composer и настроил его глобально, обновляя Kernel.php. Это должно работать и на веб-маршруте.

kernel.php

protected $middleware = [
   ...
  \Barryvdh\Cors\HandleCors::class,
];

Затем я настраиваю Laravel Cors , используя стандартную конфигурацию в качестве теста, чтобы разрешить любой домен.

/ конфиг / cors.php

 return [
    'supportsCredentials' => false,
    'allowedOrigins' => ['http:www.domain_b.com','https:www.domain_b.com','http:domain_b.com'],
    'allowedHeaders' => ['Access-Control-Allow-Origin', 'X-CSRF-TOKEN', 'Content-Type', 'X-Requested-With'],
    'allowedMethods' => ['*'], // ex: ['GET', 'POST', 'PUT',  'DELETE']
    'exposedHeaders' => [],
    'maxAge' => 0,
];

Конфигурация axios:

(domain_a) / Repository.js

import axios from 'axios/index';

const baseDomain = "https://domain_a";
const baseURL = `${baseDomain}`;

let withCredentials = false;

const token = document.head.querySelector('meta[name="csrf-token"]');

const headers = {
   'X-CSRF-TOKEN': token.content,
   'Access-Control-Allow-Origin': '*',
   'X-Requested-With': 'XMLHttpRequest',
   'Content-Type': 'application/json',
};


export default axios.create({
    baseURL,
    withCredentials: withCredentials,
    headers: headers
});

GET-запросы также фильтруются, PUT-запрос возвращает ошибку 419, почему? Я установил 'allowMethods' => ['*'], чтобы он работал ... чего мне не хватает?

[ EDIT ]

ON debug Я получил эту ошибку прямо сейчас ...

сообщение: «Несоответствие токена CSRF».

Почему POST не получает токен заголовка?

Я попытался передать токен POST так:

 const token = document.head.querySelector('meta[name="csrf-token"]');
const options = {
    headers: {
        'Authorization' :  'bearer '+token.content,
    }
};
const body = {};
return Repository.post(`${resource}/${$playerId}/${$cozzaloID}`, body, options)

Ответ предполетного заголовка

 Access-Control-Allow-Headers: authorization, content-type, x-requested-with, x-csrf-token
 Access-Control-Allow-Methods: POST
 Access-Control-Allow-Origin: http://www.******.**
 Cache-Control: no-cache, private
 Connection: Keep-Alive
 Content-Length: 0
 Content-Type: text/html; charset=UTF-8
 Date: Mon, 01 Jul 2019 05:14:22 GMT
 Keep-Alive: timeout=5, max=98
 Server: Apache
 X-Powered-By: PHP/7.1.30, PleskLin

Ответ заголовка :

Access-Control-Allow-Origin: http://www.xxxxxxx.xx
Cache-Control: no-cache, private
Connection: Keep-Alive
Content-Type: application/json
Date: Mon, 01 Jul 2019 05:14:22 GMT
Keep-Alive: timeout=5, max=97
Server: Apache
Transfer-Encoding: chunked
Vary: Origin,Authorization
X-Powered-By: PHP/7.1.30, PleskLin

Запрос заголовка :

Provisional headers are shown
Accept: application/json, text/plain, */*
Authorization: Bearer jW6pFcVlkKyApCxtZIlfaHDPMSFWCWcbnPPTQ7EJ
Content-Type: application/json
Origin: http://www.xxxxxxx.xx 
Referer: http://www.xxxxxx.xx/players/739
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) 
AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.100 
Safari/537.36
X-CSRF-TOKEN: jW6pFcVlkKyApCxtZIlfaHDPMSFWCWcbnPPTQ7EJ
X-Requested-With: XMLHttpRequest

Примечание по поводу токена : все должно быть в порядке, поскольку оно совпадает с запросом GET, выполненным в той же задаче.

1 Ответ

2 голосов
/ 01 июля 2019

Пожалуйста, используйте маршруты / api.php для маршрутизации API, не используйте маршруты / web.php для API.

Если вы хотите использовать поддомен, внесите необходимые изменения в следующем файле:

app / Providers / RouteServiceProvider.php

Оригинал:

protected function mapApiRoutes() {
    Route::prefix('api')
    ->middleware('api')
    ->namespace($this->namespace)
    ->group(base_path('routes/api.php'));
}

Обновлено:

protected function mapApiRoutes() {
    Route::domain('api.' .  env('APP_URL'))
    ->middleware('api')
    ->namespace($this->namespace)
    ->group(base_path('routes/api.php'));
}
...