Laravel 5.6 - Как аутентифицировать API, используя сеансы для одной и той же папки SPA?

У меня есть React SPA в том же проекте Laravel. Вход / регистрация / выход из системы и все другие представления js находятся в папке js и используют вызовы axios api для всех POST/GET Запросы. Я хочу использовать веб-аутентификацию на основе сеанса Laravel по умолчанию для встроенного SPA, поскольку он находится в той же папке проекта и будет единственным клиентом javascript, который обращается к нему. Этот API-интерфейс не должен быть открыт для публики, только для этого приложения реагирования, и это SPA для скорости и хорошего пользовательского опыта вместо полной перезагрузки страницы.

Я уже пытался использовать Passport, и уже больше месяца не могу заставить его работать как положено. Я не хочу иметь дело с токенами, токенами доступа, обновлять токены, отзывать токены, CSRF и т. Д. Просто из коробки простая аутентификация на основе сеансов Laravel, которая так легко работает в сети, но хочу, чтобы она работала в моем приложении реакции. Единственный блейд-файл index.blade.php который включает в себя реакцию app.js

Есть идеи, как этого добиться?

ОБНОВЛЕНИЕ 1:

После реализации предложения @ceejayoz:

Вы должны добавить различные промежуточные программы Session/Cookie в app/Http/Kernel.php (такие как \Illuminate\Session\Middleware\StartSession::class) к маршрутам API.

Я добавил в $middlewareGroups.api чтобы соответствовать web промежуточное ПО в app/Http/Kernel.php:

'api' => [
    'throttle:60,1',
    'bindings',
    // Newly added middleware to match web middleware
    \App\Http\Middleware\EncryptCookies::class
    \Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
    \Illuminate\Session\Middleware\StartSession::class,
    \Illuminate\View\Middleware\ShareErrorsFromSession::class,
    \App\Http\Middleware\VerifyCsrfToken::class,
    \Illuminate\Routing\Middleware\SubstituteBindings::class,
],

Я понял, что возникли две проблемы:

  1. В таблице сессий, даже если вы не вошли в систему, при загрузке домашней страницы приложения (или любой другой страницы) несколько сеансов вставляются в sessions Таблица. Разве новый сеанс не должен быть вставлен в эту таблицу только после входа пользователя?
  2. После входа пользователя в систему, обновления страницы вручную в браузере и вызова по защищенному маршруту, я получаю 401 Unauthenticated что указывает мне на этот метод в Illuminate/Auth/GuardHelpers.php:

    public function authenticate() {
        if (! is_null($user = $this->user())) {
            return $user;
        }
    
        throw new AuthenticationException; // throws this 401 exception on logged in page refresh when fetching data from private route
    }
    

Некоторые дополнительные заметки:

  • В config/auth.php Я обновил guards.api.driver в session вместо token,
  • В routes/api.php У меня есть защищенные маршруты, завернутые в промежуточное программное обеспечение аутентификации, как это: Route::group(['middleware' => 'auth'], function() { PRIVATE ROUTES HERE }
  • В config/session.php я имею 'domain' => '.mydomain.com'
  • Я отправляю обратно эти заголовки с каждым запросом axios api следующим образом:

    window.axios.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest';
    let token = document.head.querySelector('meta[name="csrf-token"]');
    window.axios.defaults.headers.common['X-CSRF-TOKEN'] = token.content;
    

Любая идея, как мы можем исправить эти 2 проблемы?

2 ответа

Решение

Похоже, ваш сеанс не был постоянным.

Проверьте, изменили ли вы какие-либо значения в config/session.php это может создать проблемы.

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

Из комментариев @Wonka решил свою проблему, изменив

'same_site' => 'strict'

в

'same_site' => null

Это выполнимо (и я сделал то же самое для некоторых приложений).

По умолчанию маршруты в routes/api.php нет доступных сеансов, но вы можете добавить различные промежуточные программы Session/Cookie в app/Http/Kernel.php (такие вещи, как \Illuminate\Session\Middleware\StartSession::class) к маршрутам API.

Как и @ljubadr, вы также можете поместить маршруты API прямо в routes/web.php вместо этого, хотя это, вероятно, означало бы, что вам нужно будет внести другие изменения (например, снять защиту CSRF с веб-маршрутов).

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