Slim 4 psr7-sessions/storageless (solved)

Hi all!
I’m trying to use psr7-sessions/storageless with Slim4:

class    MiddlewareInvokableClass {
        /*
             * @param ServerRequest $request PSR-7 request
             * @param RequestHandler $handler PSR-15 request handler
             *
             * @return Response
             */
            public function __invoke(Request $request, RequestHandler $handler): Response
            {        
                $session = SessionMiddleware::fromAsymmetricKeyDefaults($privateKey, $publicKey, 1200);
                
                return $session->process($request, $handler);
            }
    }

I’m call it as:

$app->add(new MiddlewareInvokableClass());

But this is no take effect - no cookies send.
Where I’m wrong? Could you help please?

Maybe dflydev/fig-cookies is missing?

Since PSR7Session depends on lcobucci/jwt , lcobucci/clock , and dflydev/fig-cookies , you need to require them as well, since with this sort of setup you are explicitly using those components:

composer require "lcobucci/jwt:~3.1" 
composer require "lcobucci/clock:^1.1.0" 
composer require "dflydev/fig-cookies:^1.0.1"

Read more

Sure not missing. Those components installed. They anyway will be installed because required by storageless.

Did you add session_start() in your index.php? If not, that’s why it’s not sending cookie headers back.

I dont need session. Why you think about cookie headers cant send without session?

Cookies are a mechanism for storing data in the remote browser
PHP: Cookies - Manual

“storing data in the remote browser” - how this can related with server-side sessions?

P.S. Anyway, i’m tried to use your solution - with expected result: native php session started, storageless cookie still not sending.

It looks like the psr7-sessions/storageless is sending only a cookie when you access the LazySession instance via HTTPS. Example:

The custom Session middleware

use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Server\MiddlewareInterface;
use Psr\Http\Server\RequestHandlerInterface;
use PSR7Sessions\Storageless\Http\SessionMiddleware;

class MiddlewareInvokableClass implements MiddlewareInterface
{
    /**
     * @param ServerRequestInterface $request
     * @param RequestHandlerInterface $handler
     * @return ResponseInterface
     */
    public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface
    {
        $privateKey = file_get_contents(__DIR__ . '/../resources/keys/private_key.pem');
        $publicKey = file_get_contents(__DIR__ . '/../resources/keys/public_key.pem');
        $session = SessionMiddleware::fromAsymmetricKeyDefaults($privateKey, $publicKey, 1200 * 10);

        return $session->process($request, $handler);
    }
}

Add the middleware:

use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Server\MiddlewareInterface;
use Psr\Http\Server\RequestHandlerInterface;
use PSR7Sessions\Storageless\Http\SessionMiddleware;
use Slim\Factory\AppFactory;

require_once __DIR__ . '/../vendor/autoload.php';

$app = AppFactory::create();

$app->addRoutingMiddleware();
$app->add(new MiddlewareInvokableClass());

// This works too
// $app->add(SessionMiddleware::fromAsymmetricKeyDefaults($privateKey, $publicKey, 1200));

$app->addErrorMiddleware(true, true, true);

Add a route:

$app->get('/', static function (ServerRequestInterface $request, ResponseInterface $response, $args) {
    /** @var \PSR7Sessions\Storageless\Session\LazySession $session */
    $session = $request->getAttribute(SessionMiddleware::SESSION_ATTRIBUTE);
    $session->set('counter', $session->get('counter', 0) + 1);

    $response->getBody()->write('Counter Value: ' . $session->get('counter'));

    return $response;
});

Without this route, the psr7-sessions/storageless library will send nothing.

Now you can see that the server response contains a Set-Cookie header like this:

BUT, the problem is that the browser does’t accept this cookie comming from the server.

image

This happens because HTTPS is required by default.

If you open your site via https://… then you should get the cookie:

image

3 Likes

@odan very thanks!

Sure, i’m use HTTPS.

Yes, this is was a problem. Adding this code to route make working - i’m was trying to add same code into another middleware - this is no take effect.

Thank you.

I dont need session. Why you think about cookie headers cant send without session?

@grayfolk sorry I misread the issue

1 Like

@odan when I add your proposed code to the on of your slim4 tutorial in your blog, I get this error:

Type: TypeError

Code: 0

Message: Return value of Slim\CallableResolver::bindToContainer() must be callable, null returned

File: /my/path/to/api/vendor/slim/slim/Slim/CallableResolver.php

Line: 177

any chance for me to adapt the above to your tutorial? :slight_smile:

Hi @stefanvz I have tested it already with the skeleton from the tutorial :slight_smile: