Laravel API не работает без токена CSRF (и заголовки глобально возятся со мной) - PullRequest
0 голосов
/ 24 января 2019

Я пытаюсь настроить API в своем проекте Laravel, который я хотел бы использовать с Javascript в моем собственном проекте. API не имеет состояния, поэтому, насколько я понимаю, токены CRSF теряют свою актуальность при запросе API. Я столкнулся с двумя следующими проблемами:

  1. когда я пытаюсь отправить запросы без заголовка X-CSRF-TOKEN, я получаю 401 Unauthorized

  2. Кажется, есть проблема с неправильным применением заголовков к ответу

Запросы отправляются с субдомена client.site.test на субдомен api.site.test. Я убедился, что CORS авторизован, применив промежуточное ПО «InternalCORS» к моим маршрутам API.

Промежуточное ПО - применяется ко всем маршрутам API

class InternalCors {
    public function handle($request, Closure $next) {
        header('Access-Control-Allow-Origin:  https://client.site.test');
        header('Access-Control-Allow-Headers:  Content-Type, X-Auth-Token, X-CSRF-Token, X-Requested-With, Authorization, Origin');
        header('Access-Control-Allow-Methods:  GET, POST, PUT');
        header('Access-Control-Allow-Credentials: true');
        return $next($request);
    }
}

API-маршруты

Route::middleware('auth:api')->get('/testApi', function (Request $request) {
    return response()->json($request->user()->fullName(), 200);
})->name('testApi');

Ajax-запрос

window.$.ajax({
    headers: {
        'Accept': 'application/json',
        'X-Requested-With': 'XMLHttpRequest'
    },
    xhrFields: {
       withCredentials: true
    },
    type: 'GET',
    url: 'https://api.site.test/testApi',
    success: function (response) {
        console.log(response);
    },
    error: function (xhr) {
        console.error(xhr.responseText);
    }
});

Теперь, даже с промежуточным программным обеспечением, явно разрешающим «Учетные данные», я получил ответ о том, что заголовок установлен не '' вместо 'true'. Поэтому я добавил сверху директиву Nginx:

add_header Access-Control-Allow-Credentials "true";

При указанных выше настройках ответ на запрос «401 не авторизован». Я дважды проверил, что промежуточное ПО VerifyCsrfToken включено по умолчанию только в web маршрутах, а не api .

Я бы хотел сказать, что добавление токена CRSF в запрос ajax решает проблему, , но это не так просто .. Есть 3 заголовка, которые, кажется, влияют на ответ. получить :

[CSRF]: отправляю ли я заголовок X-CSRF-TOKEN в запросе Ajax

[MIDD HEADER]: включить ли header('Access-Control-Allow-Credentials: true'); в промежуточное ПО для маршрутов API

[NGINX HEADER]: включить ли я add_header Access-Control-Allow-Credentials "true"; в конфигурацию своего сервера для маршрутов API

Вот резюме ответа на Ajax-запрос, в зависимости от установленных заголовков:

[CSRF] [MIDD HEADER] [NGINX HEADER] : value of the 'Access-Control-Allow-Credentials' header in the response is ''

[CSRF] [MIDD HEADER] [NGINX HEADER]: value of the 'Access-Control-Allow-Credentials' header in the response is 'true, true'

[CSRF] [MIDD HEADER] [NGINX HEADER]: 200 - John Smith

[CSRF] [MIDD HEADER] [NGINX HEADER] : value of the 'Access-Control-Allow-Credentials' header in the response is ''

[CSRF] [MIDD HEADER] [NGINX HEADER]: 401 Unauthorized

[CSRF] [MIDD HEADER] [NGINX HEADER]: value of the 'Access-Control-Allow-Credentials' header in the response is ''

Я в растерянности ...

1 Ответ

0 голосов
/ 24 января 2019

Вы можете отключить CSRF на нескольких маршрутах путем редактирования.

App\Http\Middleware\VerifyCsrfToken 

и добавьте свое собственное имя маршрута в защищенное

$except = [] array.

Вы можете проверить больше здесь

...