Проверка подлинности паспорта Laravel через CreateFreshApiToken всегда возвращает {"message": "Не аутентифицирован."} - PullRequest
0 голосов
/ 22 января 2019

Я пытаюсь разрешить моим пользователям после входа в систему использовать мой собственный API через Javasscript, как описано там https://laravel.com/docs/5.7/passport#consuming-your-api-with-javascript

Я установил паспорт. Мое веб-промежуточное программное обеспечение определяется как

'web' => [
        \App\Http\Middleware\EncryptCookies::class,
        \Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
        \Illuminate\Session\Middleware\StartSession::class,
        // \Barryvdh\Cors\HandleCors::class,
        // \Illuminate\Session\Middleware\AuthenticateSession::class,
        \Illuminate\View\Middleware\ShareErrorsFromSession::class,
        \App\Http\Middleware\VerifyCsrfToken::class,
        \Illuminate\Routing\Middleware\SubstituteBindings::class,
        \App\Http\Middleware\SetLocale::class,
        \Laravel\Passport\Http\Middleware\CreateFreshApiToken::class,
    ],

Я вижу, что cookie "laravel_token" действительно создается после входа в систему.

Затем я попытался отправить простой запрос get на маршрут API

window.$.ajax({
    headers: {
        'Accept': 'application/json',
        'X-Requested-With': 'XMLHttpRequest',
        'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
    },
    type: 'GET',
    url: 'https://mywebsite.test/api/testApi',
    success: function (response) {
        console.log(response);
    },
    error: function (xhr) {
        console.error(xhr.responseText);
    }
});

Единственный ответ, который мне удалось получить, это

{"message":"Unauthenticated."}

Что я мог пропустить?

Обновление

Запрос выполняется с субдомена client.mywebsite.test, и после расследования возникает проблема. Аутентификация работает хорошо при выполнении вызова ajax от mywebsite.test. Как я могу это исправить для субдомена?

Запросить заголовки при запросе с субдомена:

OPTIONS /api/testApi HTTP/1.1
Host: mywebsite.test
Connection: keep-alive
Access-Control-Request-Method: GET
Origin: https://client.mywebsite.test
Access-Control-Request-Headers: x-csrf-token,x-requested-with
Accept: */*
Referer: https://client.mywebsite.test/home

Запросить заголовки при запросе с домена:

GET /api/testApi HTTP/1.1
Host: mywebsite.test
Connection: keep-alive
X-CSRF-TOKEN: fLTkaq9p62FROutzch2iE9IF864al8adFnxptbve
X-Requested-With: XMLHttpRequest
Cookie: laravel_token=[...]; XSRF-TOKEN=[...]; mywebsite_session=[...];

Ответы [ 2 ]

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

После просмотра и просмотра и просмотра ..

Оказывается, проблема действительно в том, что куки не отправляются с запросом на CORS. Я исправил это, добавив «withCredentials» к моему вызову Ajax:

window.$.ajax({
    headers: {
        'Accept': 'application/json',
        'X-Requested-With': 'XMLHttpRequest',
        'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
    },
    xhrFields: {
       withCredentials: true
    },
    type: 'GET',
    url: 'https://mywebsite.test/api/testApi',
    success: function (response) {
        console.log(response);
    },
    error: function (xhr) {
        console.error(xhr.responseText);
    }
});

Вы также должны убедиться, что заголовки вашего ответа указывают, что учетные данные принимаются:

header('Access-Control-Allow-Credentials: true');
0 голосов
/ 22 января 2019

Это работает для меня в проекте Laravel 5.6:

<?php

namespace App\Http\Middleware;

use Illuminate\Cookie\Middleware\EncryptCookies as Middleware;

class EncryptCookies extends Middleware
{
    /**
     * The names of the cookies that should not be encrypted.
     *
     * @var array
     */
    protected static $serialize = true;

    /**
     * The names of the cookies that should not be encrypted.
     *
     * @var array
     */
    protected $except = [
        //
    ];
}

Установите свойство $serialize в true на EncryptCookies middleware.

Источник: https://laravel.com/docs/5.6/upgrade#upgrade-5.6.30

Источник: Паспорт Laravel, использующий API без JS

...