Laravel 5.3前端ajax请求,后端丢失session的问题

微信的h5产品,使用React+Laravel 5.3,一个奇怪的现象是只有正常的http请求,在server端可以得到session数据,所有的fetch api调用都无法得到session数据,导致所有的api调用返回401,需要授权。最初后端认为是前端在fetch调用的时候没有加上credentials参数,导致laravel_session cookie没有发送。

credentials:'same-origin'

后来前端加上了credentials以后,从微信开发工具里看到,cookie确实发送了,而且包含了laravel_session的cookie,然而后端始终拿不到session数据。搜索了google,stackoverflow和laravel社区,大家有很多类似的情况,但都没结果,有的说在ajax并发请求频繁的时候会出现这种情况,有的说Session Facade不是在所有的地方都可以用,有的说是Laravel 4.x的一个bug,试遍了各种办法,也没解决,最后还是在入口处打了两种请求的callstack,果然发现了不同,正常的请求比api请求多经过了几个middleware的处理,在Http/Kernel.php里为两种请求配置了不同的middleware。

protected $middlewareGroups = [
        'web' => [
            \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,
        ],

        'api' => [
            'throttle:60,1',
            'bindings',
        ],
    ];

重点就是web经过的EncryptCookies middleware去解密cookie内容,而默认的api是不经过这个步骤的,因为laravel默认api请求是无状态的,需要每一次请求在header携带必要的token完成authentication,知道了原因,改起来很简单,为api请求也加上EncryptCookies的middleware。

protected $middlewareGroups = [
        'web' => [
            \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,
        ],

        'api' => [
            \App\Http\Middleware\EncryptCookies::class,
            'throttle:60,1',
            'bindings',
        ],
    ];

Leave a Reply

Your email address will not be published. Required fields are marked *