A middleware (PSR-15) oriented session and flash message handler for PHP.
- Documentation for v6: https://odan.github.io/session/v6/
A middleware oriented session handler for PHP and Slim 4+
Home Page: https://odan.github.io/session/
License: MIT License
A middleware (PSR-15) oriented session and flash message handler for PHP.
why has the method "has" been removed?
$userData = ['a' => 1, 'b' => 2, 'c' => 3]
If a key is set such as $this->session->set('userData', $userData);
Can I use $this->session->delete('key') to remove value for key 'c'?
Hi, in the v6 documentation it is possible to use ($session->has('foo')) but I didn't find anywhere in SessionInterface, it's only in FlashInterface is it possible to return it?
When the user deletes his account, I want to log him out, redirect to home page and inform of the success via flash message.
This is what I've tried that doesn't work:
$this->session->destroy();
$this->session->start();
$this->session->getFlash()->add('success', 'Successfully deleted account. You are now logged out.');
$this->session->save();
$responseBody['redirectUrl'] = $this->responder->urlFor('home-page');
// Less important but I put it for context
return $this->responder->respondWithJson($response, $responseBody);
And then I load the page after the DELETE
Ajax call but I don't think it's very relevant as the flash messages work when I remove $this->session->destroy();
let responseBody = JSON.parse(xHttp.responseText);
if (typeof responseBody.redirectUrl !== 'undefined'){
window.location.href = responseBody.redirectUrl;
}
It seems I have something to learn about sessions.
Hi,
I would like to contribute to this package.
I use this package in pair with slim/framework
and slim/flash
packages.
In my case the problem in SessionMiddleware
- i got notice from php that session is already started. It's because registering in dependency injection container slim/flash
package assume that session is started and ready to work.
So, my idea is - improve a little bit SessionMiddleware
by wrapping session start
- $this->session->start();
+ if ($session->isStarted() === false) {
$session->start();
}
What do you think? In case of approve I'll open PR with changes.
Can you please direct me how to use SessionMiddleware to protect a route or group? I am not able to find an example.
For example, how to protect admin group here? let's say we want to check if session contains "Admin" Role then allow otherwise through an error.
$app->group('/admin', function (RouteCollectorProxy $group) { // ... })->add(SessionMiddleware::class);
Thanks in advance.
Hi, not sure where to report minor issue on your blog.
On your blog page https://odan.github.io/2021/01/15/slim4-session.html, the last line of src/Action/Auth/LoginSubmitAction.php
:
$response->withStatus(302)->withHeader('Location', $url);
...should be:
return $response->withStatus(302)->withHeader('Location', $url);
## form_endpoint.php
$flash = $session->getFlash();
$flash->set('data', [
'test' => true
]);
header('Location: ' . $_SERVER['HTTP_REFERER']);
The flash data is empty after redirection. Did I miss out something?
Hello.
Line 12 in b83dbd5
Please make this library compatible with the php 8.
Not only version 5 but also version 4.
This repository have the "PSR-15" tag but, the SessionMiddleware class does not implement the MiddlewareInterface interface from the PSR-15
Here are some initial ideas:
Odan\Session\Interfaces
SessionDoublePassMiddleware
✔️PhpSession
to Session
MemorySession
classSessionMiddleware
into its own namespace: Odan\Session\Middleware
✔️Odan\Session\Cookie
setCookieParams
and getCookieParams
SessionException
instead of returning false for errors ✔️Please add additional thoughts below.
AFAICT this interface does not implement:
I am interested in working with slim4, I have put the session middleware to work, how can I correctly implement cookies and csrf,
Thks,
Hey! Great project!
I've been using it with Slim V4 and I was wondering to use this library with the slimphp/Slim-Csrf. I know both libraries are not supposed to work together, but it would be really nice to have function to get the storage from the session. I know there's #6 but right now the links provided by @odan are not available anymore.
Any way, I'm trying to do something like:
// dependencies.php
'csrf' => function (ContainerInterface $c) {
$responseFactory = $c->get(ResponseFactoryInterface::class);
/** @var SessionInterface $session */
$session = $c->get(SessionInterface::class);
$storage = $session->getStorage();
if (!$session->isStarted()) {
$session->start();
}
return new Guard($responseFactory, 'csrf', $storage);
},
This way we can pass the storage to the csrf library and make all the things work.
Here are some initial ideas:
SessionManagerInterface
to handle session operations, such as start
, save
, destroy
, getName
, etc.SessionInterface
to handle session data operations only, e.g. get
, set
SessionAwareInterface
in favor of dependency injectionExample usage
$config = [
'name' => 'app',
];
$session = new Odan\Session\PhpSession($config);
$session->start();
$session->set('key', 'test123')
// test123
$value = $session->get('key');
$flash = $session->getFlash();
$flash->add('error', 'Invalid username or password');
// This is now optional
$session->save();
Hi @odan,
In SessionMiddleware.php you are closing the session almost immediately after opening the session. Is this the correct behavior? I ask because if I comment out the line $this->session->save()
my session works correctly, but otherwise it fails.
Of course, I could be using it incorrectly. I have tried adding this line $app->addMiddleware($container->get(SessionMiddleware::class))
both as the first and the last middleware.
Could you please take a look and tell me if this is an error of my usage or in the middleware?
Thanks
Hi Odan, Thank you for this package, I'm looking into your slim-4-skeleton and see that the symfony session is used there, which one would you recommend? Thank you for your work in the slim community.
I'm having an issue where I can add flash messages from a Controller or Service class and confirm the messages are in flash storage with a debug of the getFlash()
method, but then they don't appear in the Twig template.
General usage of the get
and set
methods is working OK. For example I can authenticate a user and store their information in the session for subsequent page views.
Environment:
odan/session: 6.1.0
slim: 4.12.0
slim/twig-view: 3.2.0
php-di: 6.3.4
php-di/slim-bridge: 3.4.0
My relevant container definitions:
use Odan\Session\{
PhpSession,
SessionInterface,
SessionManagerInterface
};
use Slim\Views\{
Twig,
TwigMiddleware
};
use Twig\TwigFunction;
SessionManagerInterface::class => function (ContainerInterface $container) {
return $container->get(SessionInterface::class);
},
SessionInterface::class => function (ContainerInterface $container) {
$options = $container->get('settings')['session'];
return new PhpSession($options);
},
Twig::class => function (ContainerInterface $container) {
# truncated start of definition
$environment = $twig->getEnvironment();
$session = $container->get(SessionInterface::class);
$environment->addGlobal('flash', $session->getFlash());
# truncated rest of this definition
},
TwigMiddleware::class => function (ContainerInterface $container) {
return TwigMiddleware::createFromContainer($container->get(App::class), Twig::class);
},
In a Twig partial I have:
{%- set errors = flash.get('errors') -%}
{% if errors|length > 0 %}
{% for message in errors %}
<div class="alert alert-danger">
{{ message|raw }}
</div>
{% endfor %}
{% endif %}
Then in a Controller method:
private SessionInterface $session;
private Responder $responder;
public function __construct(
SessionInterface $session,
Responder $responder
) {
$this->session = $session;
$this->responder = $responder;
}
public function index(
ServerRequestInterface $request,
ResponseInterface $response
) {
$this->session->getFlash()->add('errors', 'Oops!');
dd($this->session->getFlash()); # enable this line to debug
return $this->responder
->withTemplate(
$response,
'account/index.twig'
);
}
That debug (dd
) call shows the message in storage:
Odan\Session\Flash Object
(
[storage:Odan\Session\Flash:private] => Array
(
[_flash] => Array
(
[errors] => Array
(
[0] => Oops!
)
)
)
)
But if I remove the debug call and let the Twig template load, it doesn't display the message.
I thought there might be an issue with scope of included Twig partials, so tried debugging directly in index.twig: {{ debug(flash) }}
shows it's a Flash object, but it appears to be empty:
Odan\Session\Flash Object
(
[storage:Odan\Session\Flash:private] => Array
(
)
[storageKey:Odan\Session\Flash:private] => _flash
)
I've also tried this with setting a flash message on one page and redirecting to another, but the same thing happens.
I realize this might be an issue with my PHP-DI configuration, but I've tried a lot of variations and haven't had luck. I wanted to ask here in case you have any examples of Slim+PHP-DI+Twig implementations of this. I checked your slim-skeleton package and didn't see it there.
Oh, almost forgot. I did try changing the order of middleware but that doesn't seem to have an impact. Initially I had:
return function (App $app) {
$app->addBodyParsingMiddleware();
# truncated ...
$app->add(SessionStartMiddleware::class);
// The RoutingMiddleware should be added after our CORS middleware so routing is performed first
$app->addRoutingMiddleware();
$app->add(TwigMiddleware::class);
$app->add(ErrorHandlerMiddleware::class);
// The ErrorMiddleware should always be the outermost middleware
$app->addErrorMiddleware(true, true, true);
};
And I tried moving the SessionStartMiddleware below the TwigMiddleware:
$app->add(TwigMiddleware::class);
$app->add(SessionStartMiddleware::class);
Thanks for any pointers you might have!
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.