Giter Site home page Giter Site logo

odan / session Goto Github PK

View Code? Open in Web Editor NEW
52.0 5.0 11.0 185 KB

A middleware oriented session handler for PHP and Slim 4+

Home Page: https://odan.github.io/session/

License: MIT License

PHP 100.00%
php session cookie psr-7 psr-15 middleware flash-messages

session's Introduction

session's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

session's Issues

Nested Session Keys

$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'?

session->has()

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?

Is it possible to destroy the session and add a new flash message in the same action?

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.

Check session before start?

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.

How to protect routes?

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.

Flash messages not preserved after redirection

## 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?

Version 5 - Roadmap

Here are some initial ideas:

Breaking Changes

  • All classes will be “final” by default. So extending will not be possible in the future. ✔️
  • Move all interface into its own namespace: Odan\Session\Interfaces
  • Remove SessionDoublePassMiddleware ✔️
  • Rename class PhpSession to Session
  • Remove MemorySession class
  • Move SessionMiddleware into its own namespace: Odan\Session\Middleware ✔️
  • Add a native PHP session cookie handler, e.g. Odan\Session\Cookie
    • Remove setCookieParams and getCookieParams
  • Move this library to selective/session

New Features

  • Add flash massages ✔️
  • Add support for dot notation using selective/array-reader
  • Throw SessionException instead of returning false for errors ✔️

Please add additional thoughts below.

How to set cookie and csrf

I am interested in working with slim4, I have put the session middleware to work, how can I correctly implement cookies and csrf,

Thks,

Provide a getStorage function for the PHPSession

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.

Version 6 - Roadmap

Here are some initial ideas:

  • Provide interface for each concern.
    • Add SessionManagerInterface to handle session operations, such as start, save, destroy, getName, etc.
    • Reduce SessionInterface to handle session data operations only, e.g. get, set
  • Make session settings "immutable"
  • Remove SessionAwareInterface in favor of dependency injection
  • Require PHP 8.0+

Example 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();

Closing session

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

Would you recommend this over symfony/session?

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.

Flash usage with Slim 4 and Twig

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!

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.