Index āŗ 8. Sessions
Explore Kittenās build-in session support and how to store data scoped to individual sessions.
Topics covered
- Kittenās
request.session
object. - Difference between first-party (good) and third-party (bad) cookies.
- Introduction to Kittenās own internal JSDB database (
_db
). - How to persist data scoped to the current session.
Different kittens for different folks
Weāve just seen how we can keep a persisted count of kittens.
The count, however, will be the same at any given time for anyone who visits the site.
So, if I visit the site from my computer and see 10 kittens and you visit the site right afterwards from your phone, youāll see 11 kittens (because my visit raised the count by one).
This is because weāre persisting a single kitten count.
But what if we wanted every person who visits the site to have their own kitten count, as special and unique as they are?
Enter, sessions.
Sessions, cookies, and JSDB
Kitten has built-in session support to make implementing sessions trivial in your sites.
Since the protocol of the web (HTTP) is stateless, we need to use a database if we want to persist information. But what if we want to persist different information for each person that visits our site?
š” Or, more precisely, for each browser that visits our site. (More precisely, you will get two different sessions if your browser has as persisted/regular mode and a temporary/private/incognito mode.)
Clearly, we need a way for our server to know that the request that just came in belongs to the same browser that sent that other request a few minutes ago. While there are different ways to do this, the method that Kitten uses is based on cookies.
š”Wait a minute⦠arenāt cookies evil things that Big Tech uses to violate your privacy?
Yes, and no.
You see, there are two types of cookies: first-party and third-party. The latter are whatās used to track you. The former enable sites to implement basic functionality like sessions.
To make it easier to remember, think of first-party cookies as the ones your mom bakes for your birthday and third-party cookies as the ones a wicked witch makes to lure little kids into her hut.
The great thing about having built-in support for sessions is that you donāt have to worry about any of this. Whenever a request comes into one of your routes, you can simply access the session object for it using:
request.session
So what it that object?
Itās simply an object thatās persisted in your siteās database.
š”You can see the session objects that are generated by your site by viewing the sessions table in your database. In Kittenās interactive shell, type:
kitten._db.sessions
While you can pop your data straight into the built-in sessions object, if you do that, you should be careful not to overwrite any of the required properties that are already in there. These are
id
,createdAt
,authenticated
,redirectToAfterSignIn
, andchallenge
. Apart from these reserved properties, you can name your properties anything you want and itās a good idea to namespace them under your own objects to minimise the risk of name clashes.Using the built-in sessions object to store per-session data is the easiest option and, as with many things in Kitten, itās there to make it easy for you to get started and to whip up quick experiments, etc. For larger/longer-lived apps where maintenance is important and where you might want to store custom datatypes (i.e., custom class instances) in your sessions, you should create your own sessions object in your own database app module and store your data and specify your custom classes there.
šØ Do not save custom classes on
request.session
or JSDB will throw an error when it tries to open the internal_db
database and cannot find your custom class to instantiate.š” Session objects are
EventEmitter
instances so you an.emit()
and listen for events on them. This is useful, for example, if you have a Streaming HTML handler and you it to be notified from others routes ā like a POST route used to upload files, for example. In fact, this is exactly what Kittenās own internal Settings app does when you upload a database backup during a database restore.
š You can check if the owner of the site is signed in by seeing if
request.session.authenticated
istrue
or not. And you can manually direct people to sign in and out by redirecting them to the/š/sign-in
and/š/sign-out
routes.
Kitten Count (with sessions)
So letās update our original persisted Kitten example to keep a separate count of Kittens for each browser that accesses it:
export default function ({ request }) {
if (!request.session.kittens) {
request.session.kittens = { count: 1 }
}
return kitten.html`
<h1>Kitten count</h1>
<p>${'š±ļø'.repeat(request.session.kittens.count++)}</p>
`
}
Now run the example using the kitten
command and hit it from different browsers. You should see that each has a different count of kittens.
To see the cookie that Kitten sets, open up the Storage tab of your browserās developer tools and look under the Cookies section.
Delete the cookie and see what happens.
You can find this example in the examples/kitten-count-sessions folder of the Kitten source code. Thereās also a more complicated session-based example in examples/trivia that uses the session to store a personās game state.
Right, now that you know how you can easily work with sessions in Kitten, how about we take a peek at an advanced feature ā Database App Modules ā a way of working with JavaScript Database (JSDB) that lets you store instances of custom classes and take advantage of type safety in your databases.
Next tutorial: Database App Modules