亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 開發 > PHP > 正文

關于擴展 Laravel 默認 Session 中間件導致的 Session 寫入失效問題分析

2024-05-04 23:42:05
字體:
來源:轉載
供稿:網友
這篇文章主要介紹了關于擴展 Laravel 默認 Session 中間件導致的 Session 寫入失效問題分析的相關資料,需要的朋友可以參考下
 

最近由于項目開發需要,手機客戶端和網頁端統一使用一套接口,為保證 會話(Session) 能夠正常且在各類情況下兼容,我希望能夠改變 SessionID 的獲取方式。默認情況下,所有網站都是通過 HTTP 請求的 Header 頭部中的 Cookie 實現的,通過 Cookie 中指定的 SessionID 來關聯到服務端對應數據,從而實現會話功能。

但對于手機客戶端,可能并不會支持原始的 Cookie,亦或者根據平臺需要而屏蔽,因此開發中要求通過增加一個請求頭 X-Session-Token 來標識 SessionID。在 Laravel 框架中,實現 Session 初始化、讀取和啟動,都是通過 Illuminate/Session/Middleware/StartSession 這個中間件實現的,該中間件有一個關鍵方法 getSession ,這個方法就是獲取 SessionId 從而告知 Session 組件以什么憑據恢復 Session 數據。

該中間件注冊于 app/Http/Kernel.php 文件下。

我新建了一個類繼承該中間件,同時替換了在 app/Http/Kernel.php 下的注冊的地方,原來的 getSession 方法源碼如下:

public function getSession(Request $request){$session = $this->manager->driver();$session->setId($request->cookies->get($session->getName()));return $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;}

但是麻煩也隨之而來。。。

修改完后,推送至分支,在合并至主開發分支之前往往需要跑一下單元測試,不幸的是,之前通過的 Case 這回竟然報錯,問題是 CSRF 組件 報出 Token 錯誤,而我們在這一處提供的 Token 跟平時并無二致,問題肯定出在 Session 上。

值得注意的是,我修改中間件的代碼,對框架的影響可以說根本沒有,事實上也確實沒有,因為我將我自己創建的中間件代碼修改成繼承的中間件代碼一致也無濟于事,但奇怪的是,在我將中間件換回原來的中間件就沒有這個問題。

于是我將正常情況下和非正常情況下的代碼都跑了一遍,在關鍵處斷點調試,發現問題出在中間件的一個重要屬性 $sessionHandled , 若該值為 false 則會引起我們之前的狀況。關鍵在于,中間件啟動之時,都會走 handle 方法,而對于 Session 這個中間件, handle 方法的第一行代碼就是:

$this->sessionHandled = true;

Interesting。。。

我們知道。Laravel 框架的特色是其 IoC 容器,框架中初始化各種類都是由其負責以實現各種依賴注入,以保證組件間的松耦合。中間件定然不例外。要知道,單例和普通實例最大的區別在于無論創建多少次,單例永遠都是一個,實例中的屬性不會被初始化,因此無問題的中間件必然是一個單例,而我自己創建的中間件只是個普通的類的實例。但本著知其然更要知其所以然,我需要確認我這一想法(其實解決辦法已經想到了,后面說)。

那么問題大致就在于初始化中間件這塊了,于是不得不打起精神,仔細理一下 Laravel 的啟動代碼。而這里面的重點,在于一個叫 Illuminate/Pipeline/Pipeline 的類。

這個類有三個重要方法 send 、 through 、 then 。其中 then 是開始一切的鑰匙。這個類主要是連續執行幾個框架啟動步驟的玩意兒,首先是初始化處理過程需要的組件(Request 和 中間件),其次是將請求通過這些處理組件構成的堆棧(一堆中間件和路由派發組件),最后是返回處理結果(Response)。

可以說這玩意兒是 Laravel Http 部分的核心(額,,本來就是 Kernel)。那么之前的問題就在于 Pipeline 的 then 方法和其調用的 getSlice 方法,直接觀察 getSlice 方法,可以發現它負責的是生成處理堆棧,并實例化 Middleware (中間件)類,整個方法代碼如下:

protected function getSlice(){return function ($stack, $pipe) {return function ($passable) use ($stack, $pipe) {if ($pipe instanceof Closure) {return call_user_func($pipe, $passable, $stack);} else {list($name, $parameters) = $this->parsePipeString($pipe);return call_user_func_array([$this->container->make($name), $this->method],array_merge([$passable, $stack], $parameters));}};};}

可以注意到 $this->container->make($name) ,這意味著其初始化一個中間件類,單純的就是 make,若其不是單例則反復 new ,導致之前的屬性被初始化。

那么解決辦法也顯而易見面,使其成為一個單例。

我在 app/Providers/AppServiceProvider.php 的 register 方法中添加如下一行代碼,就解決了之前的問題:

$this->app->singleton(SessionStart::class); // SessionStart 是我那個中間件類名

以上給大家介紹了擴展 Laravel 默認 Session 中間件導致的 Session 寫入失效問題分析的全部內容,希望大家喜歡。



注:相關教程知識閱讀請移步到PHP教程頻道。
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
国产综合久久久久| 欧美韩国理论所午夜片917电影| 96sao精品视频在线观看| 亚洲乱码国产乱码精品精天堂| 欧美自拍视频在线| 亚洲精品美女久久久久| 一区二区三区回区在观看免费视频| 欧美精品久久一区二区| 人妖精品videosex性欧美| 91欧美激情另类亚洲| 日韩精品在线视频观看| 国产精品∨欧美精品v日韩精品| 中文字幕亚洲一区二区三区五十路| 午夜精品久久久久久久男人的天堂| 97久久久免费福利网址| 91精品国产高清久久久久久久久| 色妞欧美日韩在线| 黄色成人在线播放| 国产精品亚洲аv天堂网| 国产视频综合在线| 日韩网站在线观看| 亚洲精品在线91| 日韩欧美国产成人| 欧美精品videosex极品1| 国产日韩欧美在线视频观看| 亚洲精品狠狠操| 色婷婷综合久久久久| 久久精品视频中文字幕| 国产热re99久久6国产精品| 亚洲成人av在线播放| 疯狂做受xxxx欧美肥白少妇| 日韩精品视频观看| 狠狠躁夜夜躁人人爽天天天天97| 亚洲美腿欧美激情另类| 成人免费xxxxx在线观看| 国产ts人妖一区二区三区| 欧美成人免费全部| 免费不卡在线观看av| 国产精品成久久久久三级| 2020国产精品视频| 久久久久久久久久久免费| 欧美大尺度激情区在线播放| 8090成年在线看片午夜| 国产精品丝袜久久久久久不卡| 91久久精品日日躁夜夜躁国产| 亚洲第一在线视频| 国产aaa精品| 日韩亚洲成人av在线| 成人激情视频在线| 色偷偷偷亚洲综合网另类| 亚洲精品在线不卡| 亚洲综合成人婷婷小说| 国模精品一区二区三区色天香| 中文字幕日韩专区| 国自在线精品视频| 日韩av在线网址| 成人看片人aa| 国产成人一区三区| 色偷偷91综合久久噜噜| 亚洲sss综合天堂久久| 国产精品久久久久久久久免费| 精品色蜜蜜精品视频在线观看| 国产午夜精品全部视频播放| 国产精品久久久久aaaa九色| 亚洲电影免费观看高清完整版| 国产成人亚洲综合青青| 日韩精品中文字幕在线播放| 国产精品视频一| 国产精品免费一区| 国产精品狠色婷| 97免费视频在线播放| 欧美视频13p| 97久久超碰福利国产精品…| 国产精品jvid在线观看蜜臀| 国产精品一区二区久久精品| 欧美日韩一区二区在线播放| 亚洲美女精品久久| 岛国av在线不卡| 亚洲四色影视在线观看| 欧美野外猛男的大粗鳮| 91极品视频在线| 亚洲人a成www在线影院| 热久久这里只有| 亚洲国产精彩中文乱码av| 国产有码在线一区二区视频| 亚洲欧洲在线看| 国产精品视频久久久久| 精品国产精品自拍| 91夜夜揉人人捏人人添红杏| 亚洲亚裔videos黑人hd| 欧美大片在线看| 国产一区二区美女视频| 日韩国产高清视频在线| 国产日韩在线播放| 亚洲黄色免费三级| 精品国内产的精品视频在线观看| 亚洲欧美制服中文字幕| 777国产偷窥盗摄精品视频| 国产伦精品一区二区三区精品视频| 国产精品扒开腿做爽爽爽的视频| 91久热免费在线视频| 69av成年福利视频| 欧美激情伊人电影| 久久成年人免费电影| 色与欲影视天天看综合网| 精品高清一区二区三区| 欧美午夜美女看片| 国产精品免费在线免费| 国产ts人妖一区二区三区| 国产欧美日韩中文字幕| 日韩精品在线观看视频| 久久影院资源网| www.色综合| 国产不卡av在线| 亚洲白虎美女被爆操| 懂色av影视一区二区三区| 在线观看精品自拍私拍| 欧美影院成年免费版| 欧美色视频日本高清在线观看| 亚洲最新中文字幕| 久热精品视频在线免费观看| 日韩成人激情视频| 日韩精品在线视频美女| 亚洲xxx大片| 欧美自拍视频在线观看| 午夜美女久久久久爽久久| 国产日韩欧美在线观看| 国内揄拍国内精品| 欧美在线激情网| 久久久久久久999| www.欧美精品| 色阁综合伊人av| 国产日韩av高清| 欧美日韩美女视频| y97精品国产97久久久久久| 日韩av123| 国产精品一区二区电影| 国产成人在线亚洲欧美| 奇米成人av国产一区二区三区| 精品国产精品自拍| 日韩av网址在线观看| 欧美日韩精品在线播放| 日韩有码在线观看| 97超级碰在线看视频免费在线看| 国产亚洲视频中文字幕视频| 国产91成人在在线播放| 97精品一区二区视频在线观看| 91精品国产九九九久久久亚洲| 黑人巨大精品欧美一区二区三区| 在线电影中文日韩| 亚洲人成在线观看网站高清| 97精品一区二区视频在线观看| 伊人久久久久久久久久久| 国产丝袜精品第一页| 成人在线小视频| 综合激情国产一区| 亚洲国产婷婷香蕉久久久久久| 国产成人综合久久| 久久中文字幕在线视频| 亚洲精品一区二区三区不| 久久国产一区二区三区| 久久精品视频中文字幕| 亚洲a级在线播放观看| 中文国产成人精品久久一|