svelte-kit-cookie-session-patch
TypeScript icon, indicating that this package has built-in type declarations

1.4.1 • Public • Published

Svelte Kit Cookie Session License Latest Stable Version

⚒️ Encrypted "stateless" cookie sessions for SvelteKit


Check out, Svemix if you want to have a better developer experience using SvelteKit. Svemix can be seen as an full stack addition to Kit. It let's you write server side code inside .svelte files, has session handling on the next level with auto client session updates, loaders and actions that run on the server and even working with javascript disabled, also provides you with meta/SEO handling.


This SvelteKit backend utility allows you to create a session to be stored in the browser cookies via a encrypted seal. This provides strong client/"stateless" sessions.

The seal stored on the client contains the session data, not your server, making it a "stateless" session from the server point of view. This is a different take than express-session where the cookie contains a session ID to then be used to map data on the server-side.


By default the cookie has an expiration time of 7 days, set via [expires] which should be a number in days.


Installation

Install into dependencies

npm i svelte-kit-cookie-session

yarn add svelte-kit-cookie-session

⚠️ Because of some vite issues #14 #15: you should add the following to your svelte.config!

const config = {
  kit: {
    vite: {
      optimizeDeps: {
        exclude: ["svelte-kit-cookie-session"],
      },
    },
  },
};

Usage

You can find an example implementation here Example.

The secret is a private key or list of private keys you must pass at runtime, it should be at least 32 characters long. Use Password Generator to generate strong secrets.

⚠️ You should always store secrets in secret environment variables on your platform.

Initializing

src/hooks.ts || src/hooks/index.ts

import { handleSession } from "svelte-kit-cookie-session";

/** @type {import('@sveltejs/kit').GetSession} */
export async function getSession({ locals }) {
  return locals.session.data;
}

// You can do it like this, without passing a own handle function
export const handle = handleSession({
  secret: "SOME_COMPLEX_SECRET_AT_LEAST_32_CHARS",
});

// Or pass your handle function as second argument to handleSession

export const handle = handleSession(
  {
    secret: "SOME_COMPLEX_SECRET_AT_LEAST_32_CHARS",
  },
  ({ request, resolve }) => {
    // request.locals is populated with the session `request.locals.session`

    // Do anything you want here
    return resolve(request);
  }
);

♻️ Secret rotation is supported. It allows you to change the secret used to sign and encrypt sessions while still being able to decrypt sessions that were created with a previous secret.

This is useful if you want to:

  • rotate secrets for better security every two (or more, or less) weeks
  • change the secret you previously used because it leaked somewhere (😱)

Then you can use multiple secrets:

Week 1:

export const handle = handleSession({
  secret: "SOME_COMPLEX_SECRET_AT_LEAST_32_CHARS",
});

Week 2:

export const handle = handleSession({
  secret: [
    {
      id: 2,
      secret: "SOME_OTHER_COMPLEX_SECRET_AT_LEAST_32_CHARS",
    },
    {
      id: 1,
      secret: "SOME_COMPLEX_SECRET_AT_LEAST_32_CHARS",
    },
  ],
});

Notes:

  • id is required so that we do not have to try every secret in the list when decrypting (the id is part of the cookies value).
  • The secret used to encrypt session data is always the first one in the array, so when rotating to put a new secret, it must be first in the array list
  • Even if you do not provide an array at first, you can always move to array based secret afterwards, knowing that your first password (string) was given {id:1} automatically.

Setting The Session

If the session already exists, the data get's updated but the expiration time stays the same

The only way to set the session is setting the locals.session.data to an object

src/routes/login.ts

/** @type {import('@sveltejs/kit').RequestHandler} */
export async function post({ locals, body }) {
  locals.session.data = body;

  return {
    body: locals.session.data,
  };
}

Accessing The Session

After initializing the session, your locals will be filled with a session JS Proxy, this Proxy automatically sets the cookie if you set the locals.session.data to something and receive the current data via locals.session.data only. To see this in action add a console.log(locals.session) it will be empty. Only if you add an console.log(locals.session.data) and access the data it will output the current data. So if you wonder why is my session not filled, this is why

src/routes/api/me.ts

/** @type {import('@sveltejs/kit').RequestHandler} */
export async function get({ locals, body }) {
  // console.log(locals.session) will be empty

  // Access your data via locals.session.data -> this should always be an object.
  const currentUser = locals.session.data?.user;

  return {
    body: {
      me: currentUser,
    },
  };
}

Destroying the Session

src/routes/logout.ts

/** @type {import('@sveltejs/kit').RequestHandler} */
export async function del({ locals }) {
  locals.session.destroy();

  return {
    body: {
      ok: true,
    },
  };
}

Refresh the session with the same data but renew the expiration date.

src/routes/refresh.ts

/** @type {import('@sveltejs/kit').RequestHandler} */
export async function put({ locals, body }) {
  locals.session.refresh(/** Optional new expiration time in days */);

  return {
    body: locals.session.data,
  };
}

Refresh the session expiration on every request Rolling -> default is false!

Note this currently only fires if a session is already existing

handleSession({
  rolling: true,
});

Express/Connect Integration

This library can integrate with express, polka or any other connect compatible middleware layer.

import express from "express";
import { sessionMiddleware } from "svelte-kit-cookie-session";

const app = express();

app.use(
  sessionMiddleware({ secret: "A_VERY_SECRET_SECRET_AT_LEAST_32_CHARS_LONG" })
);

app.get("/", (req, res) => {
  const sessionData = req.session.data;
  const views = sessionData.views ?? 0;
  req.session.data = { views: views + 1 };
  return res.json({ views: req.session.data.views });
});

app.listen(4004, () => {
  console.log("Listening on http://localhost:4004");
});

Package Sidebar

Install

npm i svelte-kit-cookie-session-patch

Weekly Downloads

12

Version

1.4.1

License

MIT

Unpacked Size

97.8 kB

Total Files

44

Last publish

Collaborators

  • nikkwong