zendframework / zend-expressive-session

Session middleware for PSR-7 applications
BSD 3-Clause "New" or "Revised" License
27 stars 11 forks source link

Inject SessionInterface, this should be shared session object. #12

Closed harikt closed 6 years ago

harikt commented 6 years ago

Provide a narrative description of what you are trying to accomplish:

It helps to inject the SessionInterface to constructor injection where we have no access to request. Also the Request is immutable so we cannot get the manipulated data done via withAttribute inside middleware.

Your containers can get the object any where $container->get(SessionInterface::class) . An example how this is working over : https://github.com/harikt/web.expressive/pull/26

This is to demonstrate to @Ocramius the changes I am looking for after the discussion https://discourse.zendframework.com/t/session-injection-via-constructor/319 . If every one agrees I will look into fixing the unit tests.

harikt commented 6 years ago

I have been looking / trying to understand how you were suggesting to make the changes via the factory.

The problem here to me is most of the dms/core module need IAuthSystem in the constructor. I am not the maintainer of the dms. So you know the limitations.

I think in that scenario PSR-7 itself may not be the best fit for dms .

weierophinney commented 6 years ago

I think in that scenario PSR-7 itself may not be the best fit for dms .

Maybe you can point the maintainer of dms to this thread, then, so they can understand the concerns.

harikt commented 6 years ago

Question : How many of us are actually using reactphp or amphp . The session state is only a problem when we are using those right ?

Else everything is a Request -> Response.

In that case I have another way of injecting the session object to the AuthSystem via Middleware. Only thing is we need to make sure the AuthMiddleware is the first to execute. Else there will be problems.

<?php
class AuthMiddleware 
{
    protected $auth;

    public function __construct(HktAuthSystem $auth)
    {
        $this->auth = $auth;
    }

    public function process(ServerRequestInterface $request, DelegateInterface $delegate)
    {
        $session = $request->getAttribute('session');
        $this->auth->setSession($session);
    }
}

and HktAuthSystem is shared.

I am also wondering why the session was not a problem before we were working with PSR7. What is the real problem we are trying to solve via the PSR-7 session when Aura.Session uses a wrapper which is easy to test ?

Ocramius commented 6 years ago

In that case I have another way of injecting the session object to the AuthSystem via Middleware. Only thing is we need to make sure the AuthMiddleware is the first to execute. Else there will be problems.

I built a similar system previously.

Even the url helpers in expressive work that way: capture the current route early one, re-use what was captured in the service definitions.

It is ugly, and it is a magic box that, while initially practical, becomes quite messy later on during execution, as you are forced to trash a huge amount of instantiated services that "touched" the service in question.

Go with it as a quickfix, but we should really not push it into the library code.

pine3ree commented 6 years ago

Hello @harikt

I am also wondering why the session was not a problem before we were working with PSR7

The problem does not lie in PSR-7 itself but in the underlying server implementation. Session fixation becomes a concern in asynchronous service environments where every service is usually instantiated only once and remains the same for all subsequent requests. If a service carries state, that state is likely to be shared among all the requests. If you need to implement a "traditional" session service but also support asynchronous systems, You need to make sure that its state gets reset at every client request. Having a new session container per request automatically solves this issue, because its state is not persisted.

kind regards, maks