Categories
General Technical

Strong Stateless Sessions

#war-on-state

I’ve been spending some of the Coronatime working on side projects, and recently got the chance to build something new to handle user auth in a stateless way.

Postgraphile is an open source way to quickly standup a full stack app, and having noticed people asking for refresh_token support, and seen plenty of sometimes acrimonious debate on the merits of traditional session vs JWT-based auth, I thought to myself, ‘self, enough opinions. Let’s build stateless auth ourselves & see what all the fuss is about!’

So, this is the result of my path to building so-called ‘stateless sessions’ and trying to make my progress transparent by open sourcing. I take no position on if you should use this, but it’s been working well for my needs. Especially if you need to perform a cloud native/microservice-style deployment, going stateless may be particularly attractive.

A lot of attention has gone into the details on this to arrange what I’d consider an appropriate balance of security and convenience, and maybe, just maybe, my parameters overlap with yours.

If you:

  • need to authenticate incoming HTTP requests but don’t want to hit your database/Redis every time
  • are willing to trade access_token fetches in return for tokens living 100% in the user agent, perhaps because you
  • don’t want to maintain your own Redis instance
  • prefer a frontend that avoids storing tokens in local storage
  • tolerate access_token lifetimes of 15 minutes (configurable)
  • prefer to use HttpOnly, Secure and SameSite flags
  • otherwise care about modern security best practices

…then this project, which aims to adopt a “strong but stateless” auth stance, may be interesting.

Check it out

Prefer Apollo Server? I’ve got you covered too.

If enough people like this I’ll consider publishing to NPM. Until then I’d be curious to know what you think!

Thanks to the clever people who came before me, including contributors to the OAuth spec, Ben Awad, @newsiberian for accepting my PR.


Assuming you speak JavaScript, for your next MVP or hackathon you could choose worse to start with, just saying :)

Categories
General

JWT in Apollo GraphQL

My first open source contribution of 2020 got accepted & published!

It’s a custom Apollo GraphQL Link for user auth. When I first encountered JWTs, I learned they have nicer scaling properties (vs. traditional session auth) but at the cost of FE complexity (handling token renewals). This project handles token renewal in a more seamless way and IMO delivers a nicer UX.

If you’re not a React/Apollo GraphQL developer please have my blessing to stop reading now :)

Still here? Cool, more geeky details:

Regarding Apollo 3, which should be released any day now, I was able to easily upgrade all my Apollo usage (Hooks time!), except for this link. I learned it wasn’t backwards compatible with 2. So I decided to fix that, take this library from Apollo 2 ->3, and while I was in there improve the test coverage. Gotta make the most of the Corona downtime right?

So this is a custom Apollo Link, written in TypeScript+ Jest. The Apollo Link API, if you haven’t already seen, is how you compose modular pieces to create the overall GraphQL client you want. For example if your needs grow beyond vanilla queries/mutations into subscriptions/’server push’ you’ll probably want the WebSocket Link. You also might use a custom link as your API usage gets more sophisticated e.g. if you’re interested in batching or retrying queries.

For me the best thing about this project is that from a user perspective, it’s effectively transparent – yet from a security perspective it does the token/auth dance in the proper way. Nice to see convenience and security go hand in hand for a change.

Here’s a quick refresher on the difference between vanilla sessions and JWTs. Session tokens tend to be returned in a web server response immediately after you POST a username & password. The session token is commonly stored in the browser as a cookie via the Set-Cookie HTTP header. Meanwhile with JWTs we typically deal with two tokens instead: access tokens, which are similar to session tokens in that they’re how you authenticate against an API, and tend to be short lived, e.g. 15 minutes. Refresh tokens on the other hand, live for longer, e.g. a week, and only let you get one thing: a new access token.

So when an access_token expires, the refresh_token, which might be stored as a cookie with appropriate path & security flags, is used to fetch a new access_token from the server.

In sum, what’s nice about this library is that when it detects an expired token, it intelligently queues incoming GraphQL operations and holds them until the token refresh dance is completed, at which point the queue is released and the operations can hit the server. All the while the user doesn’t have to do anything, they carry on as usual. Pretty decent balance of security and usability, at least for my needs!

Happy GraphQL adventuring.