19 ms·
Ask HN: What's the current sentiment on JWT for stateless auth tokens?
HN threads from 2016-2018 complain that JWT gives us too much rope with which to hang ourselves, and some advocate for alternatives like PASETO instead. Today it's not clear however that any alternatives like PASETO have crossed the threshold of adoption to warrant preference over JWT when choosing a stateless auth token solution.
What solution would you choose today for stateless auth tokens?
- authaway 7y agoJWTs aren't just bad because they embody poor cryptographic engineering, but they are also bad because stateless authentication in itself is poor security engineering for almost every application. > What solution would you choose today for stateless auth tokens? Issue token (=random 256 bit string), verify against cached database. If you believe this to be a significant performance issue, you are very likely wrong.
- ravenstine 7y agoIt's kinda funny how some people think that this would be a performance problem, but it's something that computers and programming languages are specifically designed to do really well.
- bpicolo 7y agoKV lookups with no dependent data are pretty much infinitely scalable with modern systems.
- DGAP 7y agoIf you like Ptacek, read this: https://latacora.micro.blog/2019/07/24/how-not-to.html https://latacora.micro.blog/2019/07/24/how-not-to.html But more importantly, why do you need stateless auth tokens?
- spookthesunset 7y ago> why do you need stateless auth tokens? So you aren't hitting some validation server on every HTTP request to validate a token. Said validation server adds a very nasty point of failure & potential for page latency. Going mostly stateless via JWT lets you balance the desire for fast token revocation times and load on your auth server. Even if your revocation time is a minute, meaning your clients need to refresh their token once every sixty seconds, that can still substantially lighten the load on your auth server. High security stuff can always validate the token on every request but stuff that doesn't matter as much can have a much more policy.
- eropple 7y ago> So you aren't hitting some validation server on every HTTP request to validate a token. This is not a real problem for the 99.9% case and you can add another nine if you aren't defaulting to "extreme conservative"on your risk analysis. A session token lookup in a Redis or a Postgres is completely trivial and cheap. ("But my auth service is over a network link," cries the architecture astronaut, who now has more problems and fewer solutions. Build simpler things, you almost certainly don't need more complex and you can build better solutions than JWT when you need them.)
- spookthesunset 7y agoJWT is much simpler architecture than looking up session tokens every request.
- eropple 7y agoUntil you need revocation. Which is to say until you need a working authentication system. JWTs solve a nonexistent problem in the 99.9% case but are so very, very bloggable that they've brainwormed the population but good.
- ceejayoz 7y agoFrankly, I just went back to sessions. Everyone thinks they're building the next Facebook, but most of us aren't gonna stress out even a single Redis instance.
- MuffinFlavored 7y agoIn that same mindset, why not just do a JWT in a cookie then?
- blackflame 7y agoBecause trusting the client with data is always a risky proposition.
- jdminhbg 7y agoSessions are no different in that respect. You need to sign your JWT or session cookie.
- ceejayoz 7y agoYou can store data in the server-side session the user is never intended to see. If you want to store that in a JWT, you're going to have to encrypt it, not just sign, and even that may clue them in that something's going on - if you perform some potentially spammy act on a site and suddenly the JWT gets updated with a big encrypted block, you probably know you tripped some flag.
- bob1029 7y agoI see no reason to sign a session cookie that was issued by and will be validated against some authentication service. Especially if the cookie is sourced from a cryptographically-secure pseudorandom sequence of bytes which is sufficiently long to avoid collisions with other such sequences (e.g. 256 bits of entropy should typically do per session cookie). In my implementations of such schemes, I will typically feed the CSPRNG output with a time-based salt into SHA256 or SHA512 in order to generate the final token, which is simply stored on both ends (user session db row on server & cookie on client). At this point, the server can simply 1:1 the supplied client token with the row in the database to determine if the session is valid and which claims to return (or which validated final server response to return as the case may be). Advantages with using a token made out of pure entropy soup are that it's consistent throughout the entire user's session, and confers absolutely zero information regarding the nature of that session. Disadvantages are honestly unclear. I feel like JWT and other stateless schemes started as a bandaid to re-couple the authentication domains of disparate business services, but by way of the various clients.
- blackflame 7y agoThe biggest thing to worry about is a hash length extension attack. https://blog.skullsecurity.org/2012/everything-you-need-to-know-about-hash-length-extension-attacks https://blog.skullsecurity.org/2012/everything-you-need-to-k... This requires avoiding the use of a MAC hashing algorithm such as sha1 or even sha256 because it's possible to append data and generate a valid signature from a previous oracle. Alternatively, you could use SHA2 to generate a 512-bit key and then truncate the key to 256 or use an HMAC
- jrockway 7y agoI am fine with using JWT-alikes for bearer tokens. Good for one request or a very time-limited duration. Some use cases: 1) Sign In with Google gives your browser a time-limited JWT that it then provides to the application you're trying to sign in to. The application's server checks the validity of the token (without having to contact Google, except for daily key refreshes) and can upgrade that to a session for your browser using its normal session-management machinery. The idea is to transfer a piece of information between two systems (Google and the server app) through an untrusted system (your browser). For that, the JWT works well enough. 2) I wrote a proxy to convert one's external SSO session cookie to a JWT internally. That ways apps can check the user without having to make any requests to a user service, and can propagate that safely to other backends. It was very time-limited (min(RPC deadline, global deadline) + a few seconds of slop in both directions) and never exposed outside of an internal network. Some anti-patterns: You don't want to store sessions in a database, so you store the state in a JWT that the user stores in their browser cache. This has the problem that you can't revoke the token when the user is fired or gets hacked, which is a big problem. (You can of course add a database that only stores revocations... but you now have that check inside your request path, so you should have just done it the other way around and saved the user from having to send you a giant cookie on every request.)
- Fellshard 7y agoAdd 'issuing date' to the token, revoke all before a given issue date by a single date field in your auth table. Effectively clears all tokens. Would that work, if done up front?
- altmind 7y agoJWT were aiming to be stateless, yet they cannot be stateless if you need them to be revocable. If you keep using plain sessions you got a SPOF, but you are immune, for a whole lot of consistency and cred management problems. http://cryto.net/~joepie91/blog/2016/06/19/stop-using-jwt-for-sessions-part-2-why-your-solution-doesnt-work/ http://cryto.net/~joepie91/blog/2016/06/19/stop-using-jwt-fo...
- deleted 7y ago[deleted]
- JMTQp8lwXL 7y agoYou can revoke all JWTs by changing the signing key on your server. All previously issued JWTs will be invalid.
- ceejayoz 7y agoSure, but that's the nuclear option. Imagine if Facebook did that every time one account was compromised or they fired a staffer?
- JMTQp8lwXL 7y agoFacebook as the largest userbase of any application in existence. Its needs may not equate to your needs. For example, an enterprise b2b app with a few hundred customers could probably "deal with" the nuclear option.
- ceejayoz 7y agoI'd be pretty upset if I got kicked out of a work app every time one of a few hundred companies fired someone (or even had to do a password reset for a security reason).
- JMTQp8lwXL 7y agoYou don't use a tool for managing your passwords? That's built into most browsers these days.
- StreamBright 7y agoI think there are two great options: - https://paseto.io https://paseto.io - http://macaroons.io http://macaroons.io I use simple http only cookies with the following setup: "cookie_name=cookie_value; Domain=sub.domain.com; Path=/; Secure; HttpOnly; SameSite=Strict; Max-Age=31557600" This is valid for a year when you can decide if you want to renew it. Everything else stays on our end and we controll sessions, permissions, etc. Javascript (in theory) cannot access these cookies.
- kcolford 7y agoAre you sure you're protected from CSRF from older browsers? There's still plenty of IE going around on old desktops in libraries and such.
- IggleSniggle 7y agoNot OP, but wrt to enterprise apps, SameSite protects from CSRF even on IE since June 2018 update. https://caniuse.com/#feat=same-site-cookie-attribute https://caniuse.com/#feat=same-site-cookie-attribute
- StreamBright 7y agoBased on the user base this is a negligible minority for us, that we do not want to care about. We can simply display an error message saying that you need to use a newer version.
- jiofih 7y agoWhat makes macaroons great? I read the whole documentation and the macaroon.js docs. It seems to be under-documented, the library last updated 3 years ago. I couldn’t really grasp how the mechanism is safe re. clients adding “self-attenuations” that would amount to a DoS on the receiving service. Is anyone using this in production?
- tptacek 7y agoCredential attenuation in Macaroons is cryptographic; it's in how the tokens are constructed. I don't see the opportunity for a DoS (that didn't exist without attenuation already). Macaroons are a really lovely, tight, purpose-built design that happens to capture a lot of things you want out of an API token, including some things that JWTs don't express naturally despite their kitchen-sink design. JWT is more popular because there are libraries for it in every language, and people don't think of tokens as a cryptographic design (or nobody would be using JWT!), they think of them as a library ecosystem. JWT is definitely the stronger library ecosystem! This is also why I probably wouldn't ever bother recommending PASETO. If you're sophisticated enough to evaluate token formats based on their intrinsic design, then you should implement Macaroons if possible (it's almost always possible). If you're not, then you're going to use JWT.
- KaiserPro 7y agoWe use encrypted JWT tokens. I'm not sure it was the best choice, but it was the simplest for our needs. Basically the developer is responsible for generating & distributing auth tokens for each device that they want to use our service. This service is designed to fit into games and AR apps, so we didn't want to force our own oauth flow on the end user. This way, the developer can generate a token on behalf of the end user, and distribute it how they see fit. (assuming one token per user, but it don;t overly matter, it's still tied to their account.)
- rvz 7y agoToday I would still use alternatives like PASETO [0] or Branca [1] tokens which the latter is a fernet-like secure alternative to JWTs. The problem with JWTs is that they are discouraged by many cryptographers due to their "cryptographic agility" and provide a mixture of protocols which includes weak ciphers and configurations to shoot the programmer in the foot. Why include insecure ciphers in the first place? The mentioned alternatives stick to a single cipher for its intended purpose. JWTs are inefficient for performance and are bloated in their data structure and have a performance hit when you parse the token to extract its properties compared with the same operation in other alternatives (simple session cookie require zero parsing and thus is faster). And using them for sessions poses it own pitfalls [2] which you are better off with the alternatives or plain old session cookies. They say that JWTs are "good when used right" but with those above footguns, that's like saying C++ is safe when used right, rather than having safe defaults. [0] https://paseto.io/ https://paseto.io/ [1] https://branca.io/ https://branca.io/ [2] http://cryto.net/~joepie91/blog/2016/06/19/stop-using-jwt-for-sessions-part-2-why-your-solution-doesnt-work/ http://cryto.net/~joepie91/blog/2016/06/19/stop-using-jwt-fo...
- cordite 7y agoAnother interesting one is Macaroons [1], although the implementations have not had much activity since 2014. [1] https://ai.google/research/pubs/pub41892 https://ai.google/research/pubs/pub41892
- justincormack 7y agoSee https://github.com/CleverCloud/biscuit/blob/master/README.md https://github.com/CleverCloud/biscuit/blob/master/README.md for a newer take on macaroons.
- cordite 7y agoThis is very interesting! Although it is very much a draft in progress. It also references a new one I haven’t seen before, https://vanadium.github.io/concepts/security.html https://vanadium.github.io/concepts/security.html
- hashamali 7y agoJWT bearer tokens have worked well in my experience, though I haven't used PASETO. The main benefit is being able to use the same authentication mechanism for mobile and web apps. The biggest drawback is the inability to revoke tokens without giving up statelessness. Keeping a KV blacklist isn't the end of the world, especially if expiration times for tokens are short. But at that point, the cost/benefit vs cookies+sessions gets blurry. Some general JWT tips: * Use a sufficiently long secret key if you're using HMAC based signing (https://auth0.com/blog/brute-forcing-hs256-is-possible-the-importance-of-using-strong-keys-to-sign-jwts/ https://auth0.com/blog/brute-forcing-hs256-is-possible-the-i...). * Use bearer tokens to avoid CSRF attack surfaces. * Avoid long (or non-existant) expiration times.
- AndrewStephens 7y agoWho cares what the current thinking is - define your problem and implement the solution that makes the most sense to you. IMHO, the problems with JWT are overblown. Yes, people have made huge mistakes implementing JWTs, but the fault lies with the implementation not the standard. Stateless authentication tokens are always going to problems with revocation. There is always going to be a limit on how much you can cram into them. These problems are not unique to JWTs. JWT has the advantage of being a standard with good support across languages. Other schemes might be slightly better at handling larger amounts of session data. Take your pick.
- ceejayoz 7y agoSome of the mistakes people commonly make - insecure ciphers, for example - should've been addressed in the standard.
- munchbunny 7y agoIn my experience, don't use JWT's for carrying application state. In more words, if you need to carry application state and you haven't outgrown the simple database cluster, then just use the tried and true formula of carrying state via SQL database. Pretty much every engineer these days understands how the architecture works, it's fast and reliable due to the sheer maturity of the components involved, and you don't add cryptography and maliciously crafted input attack surfaces to your auth system (see the recent talk at BlackHat 2019 about Outlook accepting unverified auth tokens). In this case using a predictable and mature approach is a good thing. On the other hand, JWT's work well for (1) federated authentication, though revocation is still hard, and (2) carrying authorization claims. The reason is that these aren't state in the sense of application state. They're attestations of an existing fact and you're using the signature mechanism to let one service trust another without having to talk directly to each other or to protect any shared secrets. You need to send signed payloads containing user ID's and lists of claims anyway, and JWT's meet those requirements pretty well.
- Izkata 7y ago> though revocation is still hard My understanding was that they're supposed to only last on the order of 5-10 minutes, with a fresh one created for the next set of requests instead of reusing one JWT for days. Is revocation still an issue with the expiry so short?
- save_ferris 7y agoNo, you just have to always keep in mind that if you misconfigure your application to sign a token with no expiry, you will never be able to revoke it. Period.
- losingthefight 7y agoI mean, this isn't really true though. If you forgot, you can have your JWT middleware check and if the field is missing, revoke it. There are tons of workarounds here and I have implemented them in several consulting roles. I personally always put a created and expires timestamp, bit if they aren't there, there are ways to fix the situation easily.
- dang 7y ago11 months ago: https://news.ycombinator.com/item?id=18804875 https://news.ycombinator.com/item?id=18804875 2018: https://news.ycombinator.com/item?id=18353874 https://news.ycombinator.com/item?id=18353874 https://news.ycombinator.com/item?id=16517412 https://news.ycombinator.com/item?id=16517412 2017: https://news.ycombinator.com/item?id=14290114 https://news.ycombinator.com/item?id=14290114 https://news.ycombinator.com/item?id=13865459 https://news.ycombinator.com/item?id=13865459 2016: https://news.ycombinator.com/item?id=11929267 https://news.ycombinator.com/item?id=11929267 https://news.ycombinator.com/item?id=11895440 https://news.ycombinator.com/item?id=11895440 2015: https://news.ycombinator.com/item?id=9616425 https://news.ycombinator.com/item?id=9616425 2014: https://news.ycombinator.com/item?id=8283006 https://news.ycombinator.com/item?id=8283006
- Zamicol 7y agoThe first comment from 11 months ago is wrong. >JWTs are useful, but there are a few things that are not immediately obvious. >1) They are signed not encrypted. This is not true. JWT's can be encrypted, signed, or both (nested). One might first look to see if this misconception is the fault of a poorly written spec, but it's literally in the second sentence of the abstract and plain as day in the introduction. People are simply not reading it. https://tools.ietf.org/html/rfc7519 https://tools.ietf.org/html/rfc7519 It drives me mad when people refer to JWT's as basically JWS's, ignoring the rest of the JWT standard and JOSE. The fact that these misconceptions continue to be up voted shows the broad misunderstanding of the standard.
- falcolas 7y agoOr, they highlight that the spec is overly complicated. And a complicated spec is very challenging to implement both correctly and safely. EDIT: Case in point, all the disagreements and conflicting best practices throughout the threads on this topic.
- AmericanChopper 7y agoI think complex specs are fine. Complex and under defined spec are a nightmare. I had to work on a WebAuthn project recently. That spec is rather complex, but makes perfect sense after you take the time to understand it. More recently, I had to answer a very simple question about X.509. After spending half a day reading the RFC (and about half a dozen other dependant specifications), I gave up and concluded that the question did not have an answer, the best I could come up with was some general graph theory principles relating to DIT.
- codegeek 7y agoOne of the secrity experts here at HN always recommends against it for auth. Go to the search box on HN and type "author:tptacek jwt". Make sure you are searching within comments. You will see his multiple responses over the years. I have mostly stuck to plain old server side sessions that are easy to revoke. If anyone is using Go, I highly recommend this library : https://github.com/alexedwards/scs https://github.com/alexedwards/scs
- spookthesunset 7y ago> I have mostly stuck to plain old server side sessions that are easy to revoke. But you have implicitly made a tradeoff. Your front-end infrastructure now has a very strong dependency on your auth server. Any minor hiccup in the auth system will blow up your downstream clients. Worse, in large sites you will be sending a ton of traffic to your auth server. You've also introduced a source of latency to your page-load times as each request now needs to call the auth server to validate the token. Whatever the response time of the auth system now gets added to the front-end response time. Going with tokens that can be validated on the front-end system can dramatically lighten load on your auth system and reduce your front-end response time. The only major trade-off is you can't kick somebody out instantly. The bad-actor can do whatever until the token expires--a knob you control. And even then, for shit that matters, you can always have the front-end server validate the auth token on each request anyway.
- bfrog 7y agoI feel like JWT is a poor version of aead cookies like rails uses.
- jrobn 7y agoWe need FIDO2 or some other standardized security key protocol in our devices. I recently got an Apple Watch and having to just tap on my wrist to authenticate is amazing. Would love to just be able to give a website one way to contact me and have it ping my device to authenticate with faceid, touchid, Windows hello, or an smart watch. Basically, a magic link on steroids.
- lightwin 7y agoJWT helped me to achieve authentication and authorization without needing to make a trip to database on every API call. I use to store user role code in the token. I kept the token expiry to an hour or two depending upon the usecase. Added logic to client to refresh the token right before expiry of existing token. Otherwise, on token expiry, server returns 401 and client can attempt to refresh token or send user to login page. If there is a need of instant revocation, then I can maintain a list of revoked tokens for the duration of token life (1-2 hours) in cache layer. After 1-2 hours token will be expired anyway.
- ossworkerrights 7y agoWhy do you need a db call for api request when you can just cache session data?
- andrewxdiamond 7y agoJWT are effectively that, a signed token that contains the session information. You could build a session cache, either in memory or out of process, but it would still be more work than the token approach
- dyeje 7y agoTypically, before stuff like JWT was popular, you would store a session in the db and the session id in a cookie. Then you would hit the db each request to check if the session was valid.
- ossworkerrights 7y agoWell not really. Storing session data in the db can hit your performance pretty bad. Storing them in mem is a better option.
- latortuga 7y agoThese are not mutually exclusive options. Redis is a database and runs in memory.
- Znafon 7y agoIn my experience, the idea that JWT is stateless is wrong. When your client log-out you will need to keep the token in a blacklist and check all requests against it to make sure it is not reused until it expires. Since you need to keep a list of invalid tokens, it's not easier to just use standard token. If what's you like in JWT is the ability to store a payload that your backend gets back, you can keep that in your store alongside the token and read it at the same time you check the token is valid. IMO, JWT only makes sense when an other entity is doing the authentication of your clients.
- ravenstine 7y ago> When your client log-out you will need to keep the token in a blacklist and check all requests against it to make sure it is not reused until it expires. Sounds like a great way to DOS a server by running out its disk or memory space. (unless there's some sort of rate limiting in place)
- Znafon 7y agoHow does keeping a short token in redis or other would make the application easier to DOS than any other resource?
- ravenstine 7y agoBecause keeping a blacklist means keeping a list of all invalid tokens that haven't expired. If a user creates a crapload of sessions, you have to keep a running list of all the invalid tokens until they expire, which creates a few problems. You now have to have some mechanism to clear out tokens that have expired, which totally defeats one of the benefits of JWTs. And keeping a blacklist opens up the doors to someone slamming your /session endpoint, eventually running out your storage and/or memory because the blacklist will just keep growing. Sure, you can build in rate limiting, which you should have anyway. The reason I think this is still a problem is that a lot of amateurs are going to go straight for JWT and are too inexperienced or lazy to implement rate limiting. But why add all this complexity? Just have a whitelist, and you avoid these problems.
- Zamicol 7y agoJOSE and COSE fill a void not filled by anything else on the market. Sure, Branca may compare to just a JWT, but it doesn't compare to a JWS let alone JOSE. If all you need is stateless auth tokens, use Branca or a good JWT library. IMHO, the problem is the libraries, not the JOSE(JWS/JWE/JWK/JWT/JWA) standard. IMHO, after ~4 years there's still no good Javascript or Go library for JOSE, but potentially a few good JWT focused libraries. https://blog.zamicol.com/2018/03/its-jose-not-jwt-pedantic-complaint.html https://blog.zamicol.com/2018/03/its-jose-not-jwt-pedantic-c...
- TomMarius 7y agoEven if your tokens are stateful, they should be signed.
- lifeisstillgood 7y agoI would be grateful if anyone could point to a "how to build a PKI based (client and server certificate based) ecosystem"
- MadWombat 7y agoEveryone seems to be posting the "stop using JWT" article from 2016. It has a lot of merit, but I think there is small logic hole in it. When the second part attempts to address the issues of token revocation, its only argument is "what if your blacklist is down?". But that is silly. Blacklist is part of your authentication process, if it is down you don't authenticate. Its like asking how would you serve your API if your API server is down. You won't, your server is down. Otherwise, blacklisting tokens as a way of revocation process seems just fine to me. Set reasonable expiration to the key, allow users to refresh keys, then when you need to revoke a key, add it to blacklist together with the expiration timestamp and expire it out of the blacklist at the same time the key itself would expire. You can do all of this by magic by using Redis for your blacklist storage and setting expiration on your blacklisted keys. Yes, you would need to check your blacklist on every request, but a) blacklist is going to be smaller than a list of every issued token (like you would with normal sessions) b) you don't even have to store the whole token, just calculate some hash and store that, now you only need to read a few bytes on every request instead of reading the whole session. The author does make a some good points though.
- zackbloom 7y agoIt's also possible to do your token validation in something like Cloudflare Workers and store your blacklist in Workers KV. That would mean it lives all around the world closer to your users than your origin, making it unlikely it is adding meaningful latency to check it. Disclaimer: I work at Cloudflare
- tggg33 7y agoBut there’s a limit of 5000 requests per 10 minutes with cloudflare workers. This kind of usage will never go well with that limit.
- jsty 7y agoWhere did you see that? I've skimmed their limits page [0] and there doesn't seem to be any request limits for paid plans. [0] - https://developers.cloudflare.com/workers/about/limits/ https://developers.cloudflare.com/workers/about/limits/
- markandrewj 7y agoThis isn't a technical answer, or me saying that there are not better options, however with JWT's being one of the corner stones of Oauth and OIDC, it would be hard to argue that there are not successful implementations.
- khana 7y agodo: signed and ecrypted JWT, sent to client as a secure, http-only cookie
- rolltiide 7y agoWhere’s that guy from that Oauth company that always pushed JWT, I think he was with Okta Its fine to be wrong its also hilarious
- vbezhenar 7y agoI'm doing everything by hand. Like byte array with timestamp (4 bytes), IP-address (4 or 16 bytes), user id (4 bytes) and so on, then this array is signed and converted to string using base64. I looked into JWT and it was absurdly long. I don't like to waste bytes.
- klysm 7y agoSigned how?
- vbezhenar 7y agoUsing HMAC.
- peburrows 7y ago“I don’t like to waste bytes” isn’t exactly a great reason to write off a widely accepted and deployed spec for transmitting data in a trustworthy manner and instead write your own implementation, which most likely hasn’t considered all the attack vectors the JWT (and broader JOSE) spec has considered and accounted for. I get the motivation — and I hesitate a little bit to say this — but it’s 2019, and a few “wasted” bytes on your auth token are less than inconsequential in a world where your front-end codebase mostly like “wastes” thousands (if not millions) of bytes. When it comes to securely transmitting data, it most often pays to lean on the work and research of others.
- vbezhenar 7y agoI prefer to keep it simple. JWT does not look like a simple thing.
- deathanatos 7y agoHTTP/2 HPACK compresses headers in such a way that the difference will be largely irrelevant. Most connections nowadays are such that latency is overwhelmingly more important than that many bytes. Also, IP address? You invalidate me every time I switch networks?
- mooseburger 7y agoI'm not sure I understand the people claiming you should use server side session tokens instead. How am I supposed to make that work with Angular? I have to be able to send to the client the user privileges somehow.
- jgalentine007 7y agoIt's pretty easy with authentication cookies and csrf tokens. I switched back to sessions too after messing around with jwts for a bit.
- GordonS 7y agoWhen logging in, the backend will generate some state (e.g. user privileges) and store it somewhere, alongside a random session ID. It might be stored on disk, in a database or in a KV store like redis. The backend returns this session ID in a cookie. You store this session ID as a client-side cookie, which gets sent on every request to your backend. When your backend receives a request, it will (typically using some kind of middleware) lookup the session ID in the backing store and deserialise the state. Sliding expiration is typically used, so as long as you keep making requests, you'll remain logged in. Revoking a single session ID is very easy, since you've just deleting a single row/key/line from your backing store.
- andyroid 7y agoJWTs and sessions are not in any way orthogonal in a system as a whole. We use JWTs primarily for scalable backends - if a session is setup or not in the front end is not a concern for the API backend services. In a microservice environment there could be many of these - that’s the whole point after all. And with JWTs being sent to these they can simply verify the integrity of the caller without asking a central authority. Coupled with OAuth2 and OIDC as protocols for delegation/federation and you have a system that scales extremely well. Of course, it might not be the first concern that needs to be addressed in a small startup but that doesn’t mean it doesn’t have a place.
- andersonmvd 7y agoJust use stateful tokens because if you are dealing with sessions and you are doing it right, you WILL want to revoke them at the user's will or at some suspect activity in a session. I've wrote how to revoke a JWT (https://dadario.com.br/revoking-json-web-tokens/ https://dadario.com.br/revoking-json-web-tokens/ - caveat: requires a db lookup), but if you are going through the trouble of revoking a JWT, just use a stateful session instead. It's way easier. You can use JWT to pass along user information to other components within your architecture, that's fine :)
- 013a 7y agoI think, philosophically, they're interesting, but in practice the statelessness ends up not being a huge benefit. In the few deployments I've seen, you end up observing this pattern of, first, not enough information is placed in the JWT to eliminate stupidly common database calls on every request (example: "the JWT contains a UserId, but we need a RoleId that we store on the user document to determine their authorization level. for, like, every API call.") Ok. So, two options: you can give up, admit JWTs were a weird choice, and just do everything possible to make those common database calls fast (which is a very solvable and scalable problem); or, you can go down the rabbit hole. Lets put a RoleID in the JWT. But, really, a RoleID doesn't tell us anything about the user's authz; it saves us one table join, but we need the underlying permissions/claims/authorizations/etc. We could put those in there. In other words, "stateless" is a misnomer. You just moved the state; from a single, consistent, and scalable database, to a "distributed database" where every node is a JWT held by your users. JWTs are probably fine. I just think the most claimed benefit they offer is mostly overblown. But, in the 2% of use-cases where that benefit could be exploited to the maximum, they're worth using, and they're also "fine" in the 98% of other use-cases.
- charrondev 7y agoYou could keep the role information in memory pretty easily though. A lot setups don’t have that many roles (even big enterprise deployments I’ve seen tend not be more than 1000, and that’s pretty extreme). The roles per user and auth of the user on the other scales linearly with users and is harder to keep in memory.
- madhadron 7y agoMy sentiment: use sessions in cookies the way people have for years if what you're doing is managing sessions. There isn't really such a thing as stateless auth tokens. For authentication you need revocation. For authorization, you can't stick that in a token that you send out because permissions can change. So you end up having state that you distribute everywhere anyway, so do it in the easiest way possible. Scaling fast lookups of a session key is much simpler problem.
- gremlinsinc 7y agoI was torn, but recently I found Inertia.js and love it. It uses server session for auth, and makes vue a bit like turbolinks, and I'm able to use vue without router/vuex, so for a fullstack but better at backend guy like myself it makes more sense. Look at their pingcrm for a good intro using laravel.