2

我在同一个 Laravel 项目中有一个 React SPA。login/signup/logout 和所有其他 js 视图都在 js 文件夹中,并对所有POST/GET请求使用 axios api 调用。我想为嵌入式 SPA 使用默认的基于 Laravel 会话的 Web 身份验证,因为它位于同一个项目文件夹中,并且它将是唯一的访问它的 javascript 客户端。这个 api 不需要对公众开放,只是为了这个 react 应用程序,它是一个速度和良好用户体验的 SPA,而不是整页重新加载。

我之前尝试过使用Passport,但一个多月以来,我仍然无法让它按预期工作。我不想处理令牌、访问令牌、刷新令牌、撤销令牌、CSRF 等。只是开箱即用的简单的基于 Laravel 会话的身份验证,可以在 Web 上轻松运行,但希望它可以在我的 react 应用程序上运行。唯一的刀片文件是index.blade.php包含反应的app.js

知道我们如何做到这一点吗?

更新 1:

实施@ceejayoz 的建议后:

您必须将 app/Http/Kernel.php 中的各种 Session/Cookie 中间件(诸如 \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表中,即使没有登录,在加载app首页(或任意页面)时,也会将多个session插入到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.drivertosession而不是token.
  • routes/api.php我将受保护的路由包裹在 auth 中间件中,如下所示: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;
    

知道我们如何解决这两个问题吗?

4

2 回答 2

2

看起来你的会话不是持久的。

检查您是否更改config/session.php了可能会产生问题的任何值。

您可以在此处检查默认会话配置值

从评论中,@Wonka 通过更改解决了他的问题

'same_site' => 'strict'

'same_site' => null
于 2019-01-18T21:11:21.217 回答
1

这是可行的(我自己也为某些应用程序做过同样的事情)。

默认情况下,路由中routes/api.php没有可用的会话,但您可以将各种 Session/Cookie 中间件app/Http/Kernel.php(类似\Illuminate\Session\Middleware\StartSession::class)添加到 API 路由中。

正如@ljubadr 建议的那样,您也可以将 API 路由直接放入其中routes/web.php,尽管这可能意味着您需要进行其他更改(例如从 Web 路由中删除 CSRF 保护)。

于 2019-01-16T04:06:54.460 回答