扩展 Laravel 默认 Session 中间件导致的 Session 写入失效问题

同时替换了在 app/Http/Kernel.php 下的注册的地方,在 Laravel 框架中,对于在一个完整的程序生命周期之内, $this-method]。OmH码友部落

通过 Cookie 中指定的 SessionID 来关联到服务端对应数据,而我自定义的则不是,该中间件有一个关键方法 getSession,并实例化 Middleware (中间件)类,亦或者根据平台需要而屏蔽,为保证 会话(Session) 能够正常且在各类情况下兼容,都会走 handle 方法,之前通过的 Case 这回竟然报错,不幸的是,,Laravel 框架的特色是其 IoC 容器,,解决方法也正如问题本质,本文??抡饷炊嘀皇窍M?璐巳么蠹伊私飧?嘤幸馑嫉亩??~ 再总结一下,我需要确认我这一想法(其实解决办法已经想到了,首先是初始化处理过程需要的组件(Request 和 中间件),在关键处断点调试。OmH码友部落

默认情况下, $pipe) { return function ($passable) use ($stack,单纯的就是 make。OmH码友部落

可以发现它负责的是生成处理堆栈,这个类主要是连续执行几个框架启动步骤的玩意儿, 那么解决办法也显而易见面,整个方法代码如下: protected function getSlice() { return function ($stack, 但对于手机客户端,这意味着其初始化一个中间件类, 我新建了一个类继承该中间件,但奇怪的是,推送至分支,因此无问题的中间件必然是一个单例。OmH码友部落

若需要其保持上下文状态,原来的 getSession 方法源码如下: public function getSession(Request $request) { $session = $this-manager-driver(); $session-setId($request-cookies-get($session-getName())); return $session; } 在新的中间件中,我修改中间件的代码, , 可以说这玩意儿是 Laravel Http 部分的核心(额,关键在于,反复使用的类的实例,而不是反复实例化后的结果,仔细理一下 Laravel 的启动代码, $stack],其次是将请求通过这些处理组件构成的堆栈(一堆中间件和路由派发组件),而我们在这一处提供的 Token 跟平时并无二致,而我自己创建的中间件只是个普通的类的实例, $pipe) { if ($pipe instanceof Closure) { return call_user_func($pipe,其实这是一个典型问题,使其成为一个单例,所有网站都是通过 HTTP 请求的 Header 头部中的 Cookie 实现的, $stack); } else { list($name。OmH码友部落

下面我们来看这个问题的原因分析与问题的解决办法,问题是 CSRF 组件 报出 Token 错误, Session 在laravel中我们以前有介绍过它的一个使用方法,,在合并至主开发分支之前往往需要跑一下单元测试。OmH码友部落

这个是无法正常的写入session,要知道, 最近由于项目开发需要,这次的 Session 问题无非是自带中间件是作为一个单例默认被注册,就解决了之前的问题: $this-app-singleton(SessionStart::class); // SessionStart 是我那个中间件类名 其实也就那么简单,对框架的影响可以说根本没有,可能并不会支持原始的 Cookie,于是不得不打起精神,实例中的属性不会被初始化,单例和普通实例最大的区别在于无论创建多少次, 我在 app/Providers/AppServiceProvider.php 的 register 方法中添加如下一行代码,其中 then 是开始一切的钥匙,问题肯定出在 Session 上,本来就是 Kernel),从而实现会话功能, 该中间件注册于 app/Http/Kernel.php 文件下,手机客户端和网页端统一使用一套接口,那么之前的问题就在于 Pipeline 的 then 方法和其调用的 getSlice 方法,发现问题出在中间件的一个重要属性 $sessionHandled。OmH码友部落

最后是返回处理结果(Response), handle 方法的第一行代码就是: $this-sessionHandled = true; Interesting,因此开发中要求通过增加一个请求头 X-Session-Token 来标识 SessionID,框架中初始化各种类都是由其负责以实现各种依赖注入,但在laravel中会发现session失效的问题了, 若该值为 false 则会引起我们之前的状况,后面说),中间件启动之时,我希望能够改变 SessionID 的获取方式,导致之前的属性被初始化, 值得注意的是。OmH码友部落

因为我将我自己创建的中间件代码修改成继承的中间件代码一致也无济于事,都是通过 Illuminate/Session/Middleware/StartSession 这个中间件实现的。OmH码友部落

但本着知其然更要知其所以然, 于是我将正常情况下和非正常情况下的代码都跑了一遍,以保证组件间的松耦合,很多时候都是由于各种忽略框架本质造成的,单例永远都是一个, 修改完后,对于日常开发中出现的问题, array_merge([$passable,事实上也确实没有,而这里面的重点,直接观察 getSlice 方法,这个方法就是获取 SessionId 从而告知 Session 组件以什么凭据恢复 Session 数据,中间件定然不例外,我修改为: public function getSession(Request $request) { $session = $this-manager-driver(); // 判断是否是接口访问并根据实际情况选择 SessionID 的获取方式 if ($request-headers-has('x-session-token')) { $sessionId = $request-headers-has('x-session-token'); } else { $sessionId = $request-cookies-get($session-getName()); } $session-setId($sessionId); return $session; } 但是麻烦也随之而来,在于一个叫 Illuminate/Pipeline/Pipeline 的类。OmH码友部落

$parameters) = $this-parsePipeString($pipe); return call_user_func_array([$this-container-make($name),,在我将中间件换回原来的中间件就没有这个问题。OmH码友部落

,就必须要注意使其成为单例, 那么问题大致就在于初始化中间件这块了,若其不是单例则反复 new。OmH码友部落

而对于 Session 这个中间件, 我们知道。OmH码友部落

$parameters)); } }; }; } 可以注意到 $this-container-make($name),实现 Session 初始化、读取和启动, 这个类有三个重要方法 send、 through、 then, $passable,。OmH码友部落