Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Investigate JWT vs Session IDs for Authentication #170

Closed
jesstelford opened this issue Jul 31, 2018 · 6 comments
Closed

Investigate JWT vs Session IDs for Authentication #170

jesstelford opened this issue Jul 31, 2018 · 6 comments

Comments

@jesstelford
Copy link
Contributor

See Session Authentication vs Token Authentication for more details.

tl;dr:

  • JWTs have expiry and memory implications, but are stateless so don't require any server side infrastructure
  • Session IDs can be expired instantly, are low memory, but require serve side infrastructure (especially in a multi-server environment, ie; Redis, etc).

Our current implementation is Session IDs.

See also #169

@molomby
Copy link
Member

molomby commented Sep 12, 2018

This is really just a brain-dump of some of my current thoughts on this. Apologies for it's rambling nature.

The implications of using session IDs -vs- signed tokens are truely manifold:

  • Request size - Tokens bloat out each request by at least 10s of bytes. Can be 100s depending on how they're used.
  • Centralisation - Tokens can allow authorisation decision to be made without referencing a central data store (eg. by encoding role/privilege flags info in the token) but..
    • This probably isn't how we'd use them
    • Doing so exacerbates the request bloat issue above
    • Now you have a cache invalidation issue (below)
  • Destroying sessions - Since session IDs need to be resolve in a central store they can be easily invalidated.
    • Similar functionality can be achieved by signed tokens of a separate ID (eg. a tokenId stored in the users table rather than the userId itself) but..
      • Now you're back to checking a central store with each request
      • You're limited in that you can "sign out" a specific user but not a specific session/device (probably ok?)
  • Infrastructure - Signed tokens don't require any additional storage mechanism, just a little CPU time (easy to scale). For session IDs the options are...
    • Use Redis!
      • More to setup and secure
      • Another possible point of failure
      • Annoying for small apps (eg. additional addon for heroku apps, etc.)
    • Use the app DB!
      • Bloats the DB. How does the data get cleaned up?
        • Mongo capped collection/pg cycling sequence? Still needs some management as the system grows
        • A cleanup worker? Ok, but adds some complexity/dependancies
      • Session IDs now need to be stored securely
        • Plain text or "cheap" hash? read access/access to backups can give access to live system
        • "expensive" hash (eg. bcrypt)? Performance penalty on validate unless you cache the result (additional complexity)
      • Migration issues
        • Is this DB structure created/maintained by Keystone?
        • Is it a list or a special internal system table/collection?
    • In dev, use a memory store!
      • So devs get signed out every time the app restarts? Or we have some hack to reauth? Not ideal..
  • Security/library issues - The JWT spec in particular has copped a lot of flack as a bad standard. It's easy to do badly; using a simple session ID lookup avoids many potential pitfalls.
  • DB access - If supported well, tokens can remove the need for a DB round trip
    • "If supported well"... KS loads the entire auth'ed item into the request scope meaning we'd do a DB round trip either way. This isn't technically required and (I believe) should be fixed (see Clarify/refactor session handling #303).

Tokens cop a lot of flack but I think they can make sense in both:

  • Very large apps, assuming we can refactor the full auth'ed item out of the req and GraphQL context objects
  • Very small apps where putting a session IDs in Redis/Elasticache is overkill, in the DB causes bloat and/or complexity and memory stores suck in prod and dev for various reasons

It would be nice to give app developers options. If we wanted to include a token-based session implementation we might still want to avoid JWT though. Much simpler and focused, albeit less common, token standards exists. The main contenders are:

For session IDs we should probably lean heavily towards just using Redis everywhere (inc. in dev).

@molomby
Copy link
Member

molomby commented Oct 2, 2018

Related: Allow setting the session store, #362.

@MadeByMike MadeByMike added auth and removed Airtable labels Jul 23, 2019
@stale stale bot added the needs-review label Sep 21, 2019
@keystonejs keystonejs deleted a comment from stale bot Oct 9, 2019
@stale stale bot removed the needs-review label Oct 9, 2019
@MadeByMike
Copy link
Contributor

@jesstelford is this now possible to implement with a custom session store?

@jesstelford
Copy link
Contributor Author

No, it's fundamentally a different model and not supported with custom session stores unfortunately.

@gautamsi
Copy link
Member

Should this be a session adapter which can make sure consistency in behavior when using jwt or session id?

@jesstelford
Copy link
Contributor Author

Keystone Next will continue to use tokens.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants