Analysis on the failure of Session write caused by extending the default Session middleware of Laravel, laravelsession_PHP tutorial

Source: Internet
Author: User
Laravelsession. Concerning the analysis of Session write failure caused by extended default Session middleware of Laravel, laravelsession is recently required for project development, the mobile client and the web client use a set of analysis on Session write failures caused by extended Laravel default Session middleware. laravelsession

Recently, due to project development requirements, mobile client and web client use a set of interfaces in a unified manner. to ensure normal Session and compatibility under various circumstances, I hope to change the SessionID acquisition method. By default, all websites are implemented through cookies in the Header of the HTTP request Header. the SessionID specified in the Cookie is used to associate the data on the server to implement the session function.

However, the mobile client may not support the original Cookie or block it based on the platform's needs. Therefore, you must add 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. This Middleware has a key method getSession, this method is to obtain the SessionId to inform the Session component of the creden used to restore Session data.

The middleware is registered in the app/Http/Kernel. php file.

I created a class that inherits the middleware and replaced the registration location under app/Http/Kernel. php. The original getSession method source code 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:

Public function getSession (Request $ request) {$ session = $ this-> manager-> driver (); // Determine whether the interface is accessed and select the method for obtaining the SessionID based on the actual situation 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 ;}

But the troubles also come along...

After the modification, push to the branch. before merging to the main development branch, you often need to run the unit test. Unfortunately, this error is returned when the previous Case is passed, the problem is that the CSRF component reports a Token error, and the Token we provide here is not the same as that in normal times. The problem must be in the Session.

It is worth noting that I have modified the middleware code and have no impact on the framework. In fact, it does not, it doesn't matter if I change the self-created middleware code to the inherited middleware code, but it's strange that I don't have this problem when I switch the middleware back to the original middleware.

So I ran all the code under normal and abnormal circumstances, and breakpoint debugging at key points. I found that the problem lies in an important attribute of middleware $ sessionHandled, if this value is false, it will cause our previous situation. The key is that the handle method is used when the middleware is started. for the Session middleware, the first line of code of the handle method is:

$ This-> sessionHandled = true;

Interesting...

We know. The Laravel framework features its IoC container. each type of initialization in the framework is the responsibility of it to implement various dependency injection to ensure loose coupling between components. The middleware is certainly no exception. You must know that the biggest difference between a Singleton and a common instance is that, no matter how many times a singleton is created, the singleton will always be one and the attributes in the instance will not be initialized, therefore, the non-problematic middleware must be a singleton, and the middleware I created myself is only a common class instance. But I need to confirm my idea in the spirit of knowing it, and I have come up with a solution, which will be explained later ).

The problem is that the middleware is initialized, so you have to take a look at Laravel's startup code carefully. The focus here is a class called Illuminate \ Pipeline.

This class has three important methods: send, through, and then. Then is the key to start everything. This class is mainly used to continuously execute several startup steps of the framework. The first is to initialize the components (Request and middleware) required in the processing process ), the second is the stack composed of the request processing components (a bunch of middleware and routing distribution components), and the last is the Response ).

It can be said that this is the core of Laravel Http (the amount is actually the Kernel ). The problem is that the Pipeline's then method and the getSlice method it calls directly observe the getSlice method. it can be found that it is responsible for generating the processing stack and instantiating the Middleware (Middleware) class, the code for the entire method 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));}};};}

You can note that $ this-> container-> make ($ name) means that it initializes a middleware class, which is simply make. if it is not a singleton, it repeats new, as a result, the previous attribute is initialized.

Then the solution is obvious, making it a singleton.

I added the following code to the register method of app/Providers/AppServiceProvider. php to solve the previous problem:

$ This-> app-> singleton (SessionStart: class); // SessionStart is the name of my middleware class.

The above section describes all the analysis contents of the Session write failure caused by extended default Session middleware Laravel.

Articles you may be interested in:
  • Client Solution for Session object failure
  • Asynchronous HttpContext. Current implementation of the value method (to solve the problem of asynchronous Application, Session, Cache... and other failures)
  • Multiple solutions to session invalidation caused by browser disabling
  • Solutions to the problem of iframe cross-domain and session failure
  • Eloquent (Laravel's ORM) for laravel 5 framework learning)
  • Laravel 5 framework learning form
  • Laravel 5 framework learning date, Mutator and Scope
  • Form verification for Laravel 5 framework learning
  • The relationship between Eloquent and Laravel 5 framework learning
  • Laravel 5 framework learning-user authentication
  • Laravel 5 framework (1)

Mongolaravel analyzes the issue of Session write failure caused by default Session middleware. laravelsession recently uses a set of mobile client and web client as a result of project development needs...

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.