How to use session in slim correctly?


#1

Hello,
iam trying to use sessions in slim framework to store a user object in session for authentification. I store the user object in the LoginController when passwort_verify provides true:

<?php
/**
 * Created by PhpStorm.
 * User: behme
 * Date: 24.06.2018
 * Time: 10:33
 */

namespace SlimBuild\Controller\Register;

use SlimBuild\Helper\Controller;
use Psr\Http\Message\ResponseInterface;
use SlimBuild\Helper\Password;
use SlimBuild\Helper\Session;
use SlimBuild\Model\User;

class Login extends Controller
{

    public function index($args): ResponseInterface
    {
        $data = array();
        return $this->view->render($this->response, 'Register/Login/login.twig', $data);
    }

    public function login(): ResponseInterface
    {
        $data = array();
        $params = $this->request->getParams();
        $password = new Password();
        $user = new User($this->container->get('db'));
        $user = $user->where(['email' => $params['email']])->first();
        if(($password->verify($params['password'], $user->getPassword()))) {
            $session = new Session();
            $session->set('user', $user);
            header( 'Location: ' . SITE_URL);
            exit;
        }
        return $this->view->render($this->response, 'Register/Login/login.twig', $data);
    }
}

My session class looks like:

<?php
/**
 * Created by PhpStorm.
 * User: behme
 * Date: 27.06.2018
 * Time: 11:37
 */

namespace SlimBuild\Helper;


class Session {

    private $cookieTime;

    public function __construct() {
        session_start();
        session_cache_limiter(false);
        $this->cookieTime = strtotime('+30 days');
    }

    /**
     * @param $name
     * @param $value
     */
    public function set($name, $value) {
        $_SESSION[$name] = $value;
    }

    /**
     * @param $base
     * @param $key
     * @param $value
     */
    public function setMulti($base, $key, $value) {
        $_SESSION[$base][$key] = $value;
    }

    /**
     * @param $name
     * @return mixed
     */
    public function get($name) {
        if (isset($_SESSION[$name])) {
            return $_SESSION[$name];
        }
        return $_SESSION[$name];
    }

    /**
     * @param $base
     * @param $key
     * @return mixed
     */
    public function getMulti($base, $key) {
        if (isset($_SESSION[$base][$key])) {
            return $_SESSION[$base][$key];
        }
        return $_SESSION[$base][$key];
    }

    /**
     * @param $name
     */
    public function kill($name) {
        unset($_SESSION[$name]);
    }

    /**
     * Destroy session
     */
    public function killAll() {
        session_destroy();
    }

    /**
     * @param $name
     * @param $value
     */
    public function setCookie($name, $value) {
        setcookie($name, $value, $this->cookieTime);
    }

    /**
     * @param $name
     * @return mixed
     */
    public function getCookie($name) {
        return $_COOKIE[$name];
    }

    /**
     * @param $name
     */
    public function killCookie($name) {
        setcookie($name, null);
    }
}

And when i want to use the stored session key in main view (‘General/general.twig’) or method index from GeneralController, it provides me a blank array

<?php

namespace SlimBuild\Controller;

use Psr\Http\Message\ResponseInterface;
use SlimBuild\Helper\Controller;
use SlimBuild\Helper\Session;

/**
 * Class General
 * @package SlimBuild
 *
 * @author Eugen Behm
 */
class General extends Controller
{

    /**
     * start page controller
     *
     * @return \Psr\Http\Message\ResponseInterface
     */
    public function index(): ResponseInterface
    {
        $session = new Session();
        var_dump($session->get('user'));
        die();
        return $this->view->render($this->response, 'General/general.twig', []);
    }
}

this is my routes.php:

<?php
use Slim\Http\Request;
use Slim\Http\Response;
// Index page
$App->get('/', \SlimBuild\Controller\General::class . ':index');

Can me anyone explain my mistakes or how to use sessions in slim correctly?
Thank u very much.
Eugen


#2

Hi!

  1. Your Session class should provide a start() method to start the session. Better don’t use the constructor to start the session.
  2. Then I would say start the session in a middleware to make sure that the session handler is always started.

Example session middleware

use Slim\Container;
use Slim\Http\Request;
use Slim\Http\Response;

// Session middleware
$app->add(function (Request $request, Response $response, $next) {
    /* @var Container $this */
    $session = $this->get('session');
    $session->start();
    $response = $next($request, $response);
    $session->save();
    return $response;
});

#3

Hey,
I got an exception “ContainerValueNotFoundException” with the following details:

Type: Slim\Exception\ContainerValueNotFoundException
Message: Identifier “SlimBuild\Helper\Session” is not defined.
File: C:\xampp\htdocs\immosoft\vendor\slim\slim\Slim\Container.php
Line: 120

I have type the following lines into my routes.php:

use Slim\Container;
use Slim\Http\Request;
use Slim\Http\Response;
use SlimBuild\Helper\Session;

$App->add(function (Request $request, Response $response, $next) {
    /* @var Container $this */
    $session = $this->get(Session::class);
    $session->start();
    $response = $next($request, $response);
    //$session->save();
    return $response;
});

I have uncomment the save call. Why i should have to implement a save method in Session Class?
I removed the session start in constructor and implements start as public method in Sssion Class.

Thank u.


#4

I got a 500 status (Internal Server Error) from server, when i add these lines in middleware:
https://www.slimframework.com/docs/v3/concepts/middleware.html

$app->add(function ($request, $response, $next) {
	$response = $next($request, $response);
	return $response;
});

Meanwhile i changed $App to $app.


#5

Every container entry must be defined in your dependencies.php before you can fetch it from the container.

Example (please customize it):

use Slim\Container;

$container['session'] = function (Container $container) {
    return new Session();
};

Example session middleware

use Slim\Container;
use Slim\Http\Request;
use Slim\Http\Response;

// Session middleware
$app->add(function (Request $request, Response $response, $next) {
    /* @var Container $this */
    $session = $this->get('session');
    $session->start();
    $response = $next($request, $response);
    $session->save();
    return $response;
});