8 ms·
"about session usage of JWT since it has little value " Two weeks ago, I stood in front of a room full of senior developers and architects and asked them "How
by madeuptempacct 8y ago
"about session usage of JWT since it has little value "
Two weeks ago, I stood in front of a room full of senior developers and architects and asked them "How will we avoid making a leading 'Does the user have permissions?' call or wrapping the request in a try catch in case the user doesn't have access without JWT claims.
They all got mad. Then they conceded that they don't have a solution. Do you have a solution? If not, you can't replace JWTs.
- tyleraldrich 8y agoBut... that's not really something you _have_ to avoid. Check permissions, if they fail the test -> http401 (for an API) or some user-friendly redirect. Something similar to this is how things work without JWT currently, so it's only a problem if you make it one.
- madeuptempacct 8y agoYou seriously think making a redundant call or wrapping every. single. controller into a try-catch is better than having claims pulled out in a request pipeline (before even touching the controller) and doing `if(hasAccess){do thing} else {unauthorized}`?
- CiPHPerCoder 8y agoIt sounds like you're arguing from a very specific mental model of an ACL workflow. In my CMS, I had support for granular permissions. So you could do this: if ($user->can('update')) { if ($postData) { $this->processUpdate($postData); } // display edit form } elseif ($user->can('read')) { // read-only } else { return error_403_condition(); } JWT wouldn't have helped much.
- madeuptempacct 8y agoI will look into this more and come back with what I figure out later on. Thanks.
- X-Istence 8y agoThat looks similar to a try/catch... You just called it if/else. Also, why can't you make the database request in the request pipeline, right before that "if(hasAccess)" statement. You don't need JWT for this... You are already wrapping all of your controllers...
- patates 8y agoIf your controllers are asp.net mvc controllers you can decorate them with permission attributes (see the relevant docs for your version). Pretty sure most frameworks have a way to structure your code for permission checking.
- andrewingram 8y agoIf you're not willing to risk users making requests with stale permissions (which is a risk you shouldn't accept lightly), then JWT requires that you hit something at the start of processing every request anyway. It can either be a token blacklist service (really just a key-value lookup), or it can be an auth/permission service. The auth service/query is higher per-request overhead, but it also keeps things simple. And simple is what you want unless you're dealing with ridiculous scale.
- tyleraldrich 8y agoI don't know what you're working with, but you don't need a JWT to figure out access in the request pipeline. A session ID does the same thing and allows you to associate a session to a user, and most frameworks are capable of doing this already (e.g. django has middleware that can do this)
- lvh 8y agoEven if we accept the assumption that you actually have to avoid it (I don't!),here are some: - Database permissions, including row-level security - Macaroons - PASETO - Fernet/secretbox/HMACing a JSON blob These are different approaches so it's hard to summarize, but they all either give you a property JWT doesn't or avoid a flaw JWT has. You can't seriously believe that nobody did this before 2015.
- madeuptempacct 8y agoThis is a real production issue for me, so could you please elaborate on why you think one of these (whichever you prefer) is better or link me to a source?
- CiPHPerCoder 8y agoI'm not sure how you intended this comment, but it reads a bit like a solicitation for lvh to do free work. I wrote PASETO, with a lot of feedback from cryptographers and security engineers, to avoid a lot of the design flaws of JWT. Learn more about it here: https://paragonie.com/blog/2018/03/paseto-platform-agnostic-security-tokens-is-secure-alternative-jose-standards-jwt-etc https://paragonie.com/blog/2018/03/paseto-platform-agnostic-... You can find a lot of implementations available: https://paseto.io https://paseto.io (Also: You almost certainly want to use v2)
- madeuptempacct 8y agoI wanted a link to your solution because I have never heard of it before. Not sure where you are getting the "free work" part of this from, unless you want to be paid per comment. Careful with the free advertising with PASETO there. Joking on the last two sentences, but that's how you sound when you accuse me of wanting free work. Thanks for the links.
- CiPHPerCoder 8y ago> Not sure where you are getting the "free work" part of this from, unless you want to be paid per comment. Oh, that's easy to explain. You said: > This is a real production issue for me, so could you please elaborate on why you think one of these (whichever you prefer) is better or link me to a source? Specifically: > This is a real production issue for me, If you want a cryptographer (i.e. lvh) to solve a real production issue for you, that would in most cases be a business transaction.
- kodablah 8y ago> How will we avoid making a leading 'Does the user have permissions? You don't avoid it, you do it. Gathering simple user info including permissions should be the first step at the request boundary and it can traverse the life of the request. If you foolishly use a stateless token to read permissions, you're gonna be annoyed when changes you make don't take effect immediately. I trust your seniors know this (of course different situations and caveats apply, but this is referring to the general approach).
- madeuptempacct 8y agoI am well aware of this. What you are advocating is an unnecessary database call on every single request.
- kodablah 8y agoThat's exactly what I'm advocating, it's not unnecessary, and should be trivial. If you are afraid of overhead, you can have a caching layer ala Redis or Memcache or even local process memory (but don't eagerly optimize, the costs are trivial to make this call). Either way, you need to communicate with an updated cache or a user record of store. Don't trust information sent to you from the client because it may not be accurate with updates (there are exceptions to this when you can tolerate staleness, but for the general approach this is what you want to do).
- zepolen 8y agoWhat's wrong with a db call on each request? A single server can handle over 10,000 of those per second..
- nickserv 8y agoGenerally a big DB query is made when the user enters the site or makes the first API request to load all relevant user data. Then the data is stored in a cache system, which will be faster and cheaper than having the user send the data on every request. Most modern web frameworks will do this out of the box with a little configuration. Specifically, I've had good results with Redis, applicable for the majority of web apps. In some rare cases where even local network is too slow, use of local memory storage has worked well (at the cost of greater memory usage and more complex invalidation procedures). But before optimizing user permissions, in my experience there is much more to be gained from optimizing other types of DB queries.