Laravel & Spring Session

I really like both Laravel and Spring, just one problem, Spring HTTP Sessions and Laravel Sessions do not play well together. This blog post details how I made these two technologies work together.

The first problem was that both of these technologies stored their data under different keys under Redis. The first thing that I had to do was extend the Laravel session to use a new Redis Session Handler which I called sredis in the config.

In the constructor I could define my own session-key prefix and my own expiry time.

The second problem was that Spring stores it session as a hash and Laravel stores itโ€™s session as a string key value pair. Laravel serialises and deserialises the contents of the session in the functions that call the methods below. The first thing to do was to change back the contents to objects and vise versa so that we can store them as a redis hash.

The third problem was that redis encoded the session cookie which at the time of writing seems impossible to get round so for now I put this project to rest.

Have a nice day ๐Ÿ™‚

namespace App\fstegmann\srsession;

use SessionHandlerInterface;
use Illuminate\Support\Facades\Redis;

class SpringRedisSessionHandler implements SessionHandlerInterface
{
    private $prefix = null;
    private $expire = null;

    private $redis = null;

    function __construct()
    {
        if ($this->redis == null) {
            $this->redis = Redis::connection();
        }
        $this->prefix = 'fritsstegmann.co.za:sessions:';
        $this->expire = 1800;
    }

    public function read($sessionId)
    {
        if ($this->redis == null) {
            $this->redis = Redis::connection();
        }

        $data = $this->redis->hgetall($this->prefix . $sessionId);
        foreach($data as $key => &$d) {
            $d = @unserialize($d);
        }

        return $data;
    }

    public function write($sessionId, $data)
    {
        if ($this->redis == null) {
            $this->redis = Redis::connection();
        }

        $data = @unserialize($data);

        foreach($data as $key => &$d) {
            $d = serialize($d);
        }
        $this->redis->hmset($this->prefix . $sessionId, $data);
    }

    public function destroy($sessionId)
    {
        if ($this->redis == null) {
            $this->redis = Redis::connection();
        }

        $this->redis->del($this->prefix . $sessionId);
    }

    //Unused Session Handler Methods
    public function gc($lifetime) {}
    public function open($savePath, $sessionName) {}
    public function close() {}
}
namespace App\fstegmann\srsession;

use Illuminate\Support\ServiceProvider;
use Illuminate\Support\Facades\Session;

class SpringRedisSessionServiceProvider extends ServiceProvider {

	/**
	 * Bootstrap the application services.
	 *
	 * @return void
	 */
	public function boot()
	{
        Session::extend('sredis', function($app) {
            return new SpringRedisSessionHandler;
        });
	}

	/**
	 * Register the application services.
	 *
	 * @return void
	 */
	public function register() {}
}
CACHE_DRIVER=redis
SESSION_DRIVER=sredis
QUEUE_DRIVER=redis

Leave a Reply

Your email address will not be published. Required fields are marked *