In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-01-16 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >
Share
Shulou(Shulou.com)06/03 Report--
Laravel default Session middleware caused by Session write failure problem detailed explanation, I believe that many inexperienced people do not know what to do, so this paper summarizes the causes of the problem and solutions, through this article I hope you can solve this problem.
Recently, due to the needs of project development, the mobile client and the web end use a set of interfaces. In order to ensure that the session (Session) can be normal and compatible in various situations, I hope to be able to change the way to obtain SessionID. By default, all websites are implemented through the Cookie in the Header header of the HTTP request, and the SessionID specified in the Cookie is associated with the corresponding data on the server side, thus realizing the session function.
However, for mobile clients, the original Cookie may not be supported, or it may be blocked according to the needs of the platform, so the development requires the addition of a request header X-Session-Token to identify the SessionID. In the Laravel framework, Session initialization, reading, and startup are implemented through the middleware Illuminate\ Session\ Middleware\ StartSession. The middleware has a key method, getSession, which is to get SessionId to tell the Session component under what credentials to recover Session data.
The middleware is registered under the app/Http/Kernel.php file.
I created a new class that inherits the middleware and replaces the registration under app/Http/Kernel.php. The original source code of the getSession method is as follows:
Public function getSession (Request $request) {$session = $this- > manager- > driver (); $session- > setId ($request- > cookies- > get ($session- > getName ()); return $session;}
In the new middleware, I changed it to:
Public function getSession (Request $request) {$session = $this- > manager- > driver (); / / determine whether the interface is accessed and choose the acquisition method of SessionID according to the actual situation if ($request- > headers- > has) {$sessionId = $request- > headers- > has ('xluto sessionToken');} else {$sessionId = $request- > cookies- > get ($session- > getName ());} $session- > setId ($sessionId); return $session;}
But trouble comes with it.
After the modification, push to the branch, and often need to run a unit test before merging into the main development branch. Unfortunately, the Case passed before actually reported an error this time. The problem is that the CSRF component reported an Token error, and the Token we provide here is the same as usual. The problem must be Session.
It's worth noting that I modified the middleware code and had no impact on the framework at all, and in fact it didn't, because it didn't help me to change the middleware code I created to inherit the same middleware code, but strangely, I didn't have this problem when I changed the middleware back to the original middleware.
So I ran the code under both normal and abnormal conditions, debugged at the key breakpoint, and found that the problem lies in an important attribute of the middleware, $sessionHandled, which will cause our previous situation if the value is false. The point is that when the middleware starts, it takes the handle method, and for Session, the first line of code for the handle method is:
$this- > sessionHandled = true
Interesting .
We know. Laravel framework is characterized by its IoC container. It is responsible for initializing various classes in the framework to implement various dependency injection to ensure loose coupling between components. Middleware is no exception. You know, the biggest difference between a singleton and an ordinary instance is that no matter how many times it is created, the singleton will always be one, and the properties in the instance will not be initialized, so the problem-free middleware must be a singleton. The middleware I created myself is just an instance of an ordinary class. But in order to know more about why, I need to confirm my idea (in fact, the solution has already been thought of, which will be mentioned later).
So the problem is roughly initializing the middleware, so you have to pick yourself up and take a closer look at the startup code of Laravel. The focus of this is on a class called Illuminate\ Pipeline\ Pipeline.
This class has three important methods: send, through, and then. Where then is the key to everything. This class is primarily a gadget that performs several framework startup steps in succession, first initializing the components needed for the process (Request and middleware), followed by a stack of requests through these processing components (a stack of middleware and routing dispatch components), and finally returning the processing result (Response).
It can be said that this thing is the core of the Laravel Http part (er, it is originally Kernel). Then the previous problem lies in the then method of Pipeline and the getSlice method it calls. If you look at the getSlice method directly, you can find that it is responsible for generating the processing stack and instantiating the Middleware (middleware) class. The whole method code is as follows:
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);}
Notice $this- > container- > make ($name), which means that it initializes a middleware class, which is simply make, and repeats new if it is not a singleton, causing the previous properties to be initialized.
Then the solution is also obvious, making it a single case.
I solved the previous problem by adding the following line to the register method of app/Providers/AppServiceProvider.php:
$this- > app- > singleton (SessionStart::class); / / SessionStart is my middleware class name
After reading the above, have you mastered the detailed explanation of Session write failure caused by Laravel default Session middleware? If you want to learn more skills or want to know more about it, you are welcome to follow the industry information channel, thank you for reading!
Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.
Views: 0
*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.
Continue with the installation of the previous hadoop.First, install zookooper1. Decompress zookoope
"Every 5-10 years, there's a rare product, a really special, very unusual product that's the most un
© 2024 shulou.com SLNews company. All rights reserved.