Hackernoon logoAn SPA GUI Session as a Non-HttpOnly Cookie by@Bassaganas

An SPA GUI Session as a Non-HttpOnly Cookie

Author profile picture

@BassaganasJordi Bassaganas

All things web and more.

Are you writing a single page application or SPA? If so, you'd probably want to store some session data in the user's browser in order to keep track of the GUI's state.

A common scenario is an API dealing with access control rules (ACL) where the frontend needs to do something specific according to the current user's role; for example, display a certain component to admin users only.

Today I'd like to introduce to you an interesting concept which I call the GUI session.

Be aware, GUI session data, which is stored in the browser, cannot ever contain sensitive data such as a password or an authorization token because the GUI session must be read by our JavaScript code.

It doesn't really matter if an attacker is able to gain access to it, the GUI session is saved in the user agent through one of the following mechanisms:

, or an HTTP cookie.

Now let me show you a particular implementation based on HTTP cookies as well as React, PHP and Laravel code -- please visit this GitHub repo for further details.


namespace App\Http\Controllers;

use Illuminate\Http\Request;

class AuthController extends Controller
    const COOKIE_ACCESS_TOKEN = 'access_token';
    const COOKIE_SESSION = 'session';

    public function login()
        $credentials = request(['email', 'password']);

        if (!$token = auth()->attempt($credentials)) {
            return response()->json(['error' => 'Unauthorized'], 401);

        $session = [
            'role' => auth()->user()->getAttributes()['role'],

        return response(null, 204)
            ->cookie(self::COOKIE_ACCESS_TOKEN, $token, 480)
            ->cookie(self::COOKIE_SESSION, json_encode($session), 480, null, null, null, false);

    public function logout()
        $accessTokenCookie = \Cookie::forget(self::COOKIE_ACCESS_TOKEN);
        $sessionCookie = \Cookie::forget(self::COOKIE_SESSION);

        return response(null, 204)

As you can see this is a basic authentication controller written with PHP; if successfully logged in, the server will send two cookies to the browser:


Figure 1. Login page

The former is a JWT authentication token, which is an

cookie because this is sensitive data to be protected from XSS attacks. However the latter is the GUI session, and its very nature is non-HttpOnly because we do want it to be read by our JavaScript code.

Figure 2. The user's role (admin) is stored in the GUI session cookie

As you probably know when manually refreshing URLs in a React app using

, all requests are often redirected to
and therefore the client session is lost.

It is up to the programmer to make both server-side and client-side routing work together nicely.

With the basic Laravel authentication server above, up and running, now we are in a position to write a simple custom ES6 class to just wrap the GUI session, as it is described next.

import Cookies from 'js-cookie';

const name = 'session';

export default class Session {
  static get() {
    if (Cookies.get(name)) {
      return JSON.parse(Cookies.get(name));
    return {
      role: null


class has multiple purposes, for example with it our React app will be able to make decisions such as loading CASL rules every time a page is refreshed.

import ability from './ability';
import abilityRules from '../../storage/ability-rules.json';
import Session from './Session.js';


if (Session.get()) {



Today we learned how to persist the state of a graphical user interface in a single-page application dealing with an access control list (ACL).

We went through a particular implementation based on HTTP cookies, React and Laravel.

If the user is successfully logged in, the authentication server sends two cookies to the user's browser:

. The former is an
JWT token; the latter is the so-called GUI session sent as a non-HttpOnly cookie.

No sensitive information is saved in the GUI session.

The GUI session is helpful to make smart decisions concerning the graphical user interface such as displaying certain components to certain roles only.

Please visit this GitHub repo for further details.


Join Hacker Noon

Create your free account to unlock your custom reading experience.