
JSON Web Tokens vs. Sessions - darth_mastah
https://float-middle.com/json-web-tokens-jwt-vs-sessions/
======
StevePerkins
For people using JWT as a substitute for stateful sessions, how do you handle
renewal (or revocation)?

With a traditional session, the token is set to expire after some period of
inactivity (e.g. one hour). Subsequent requests push out the expiration... so
that it's always one hour _from the last activity_ , rather than one hour
_from initial authentication_.

With JWT, the expiration time is baked into the token and seems effectively
immutable. To extend the session, you have to either:

1\. Re-authenticate from the browser every hour and store a new JWT token,
which is kind of an awful user experience, or

2\. Renew the JWT token from the server side every hour. At least in Google's
implementation, this requires the user to grant "offline access" (another
awful user experience)... and you'd need some hacky approach for replacing the
JWT token in the user's browser.

So with all the recent discussion about not using JWT for sessions, what do
you guys do? Do you simply make users re-authenticate every hour? Is there
another magic trick that no one has brought up?

In my own shop, we're using the browser's JWT token as a server-side cache
key... and storing the "real" expiration in cache so that it can be extended
(or revoked) as needed. I would be interested to know if others take a similar
approach, or have issues with that?

~~~
moyok
For this, you can use refresh tokens and set the JWT expiration to a low
interval - say 10 minutes. After every 10 minutes, the JWT
expires,authentication fails, and the client uses the refresh token to get a
new JWT. To revoke a client, revoke their refresh token. This way, though they
won't be logged out immediately, they would be logged out in a max of 10
minutes when they need to refresh again, and find out that their refresh token
is no longer valid. The point is that instead of every request touching your
DB or cache, only one request does in every 10 minutes.

~~~
zackmorris
I know this works, and I've used it, but I also find it to be the most
aggravating thing about JWT and also OAuth. With OAuth, some sites allow you
to refresh a token after it times out (so really the refresh token is the
source of truth, defeating the purpose of the OAuth token), and others only
allow you to refresh before it times out (forcing a login by the user if they
are disconnected too long, or storing their username/password in the system
keychain, making that the source of truth and again defeating the purpose of
the OAuth token).

Also a timeout of this kind is only security theater, because it may only take
moments to vacuum a client's data once a token has been skimmed.

The JWT library I'm using in Laravel blacklists tokens by storing them in
their own table, rather than invalidating them. This is self-evidently a
pretty bad vulnerability because malicious users could fill up the database,
so now the developer has to deal with that scenario.

Put all that together and I think the notion of token expiration is, well,
dumb. In fact I think timeouts of any kind are a code smell. They make
otherwise deterministic code very difficult to reason about in the edge cases.
The best thing to do is encapsulate timeout handling in a refresh layer of
some kind, once again defeating the whole purpose of timeouts in the first
place.

~~~
moyok
I have personally experienced the security disadvantage you mentioned. I used
my Google login to sign into an email client. I immediately realised that the
app was going to store all of my email data in their private servers. I
quickly went over to the Google dashboard and deauthorised the app, relieved
that they would only have been able to get my first few mails in this time.
But the app retained access to my emails, even receiving new emails for some
time. Probably because of something similar to a refresh token being revoked,
but the access token still being valid. I wanted to stop the app from
accessing my e-mails, but could not.

However, despite this disadvantage some applications just cannot afford the
load of every single request touching the DB or cache. JWT makes sense for
that particular use case when you are willing to make this compromise. Instead
of every single request touching the cache, maybe every 1000th request does
now, because of the token expiration time.

Another use case is when you need a very simple, stateless way to authenticate
users and don't require revocation. Some Oauth providers don't give you the
option to revoke access tokens, for example.

~~~
3pt14159
> despite this disadvantage some applications just cannot afford the load of
> every single request touching the DB or cache.

Disagree. This is one of the simplest things alive to distribute. Split the
query from the token do the query in the DB and the token lookup is
effectively a distributed hash table lookup (assuming the token is, say, a
UUID). Once the DB query comes back store the result pending the successful
retrieval of the token.

What's difficult is handling something like millions of concurrent video
downloads / uploads - not looking up tiny tokens.

~~~
paulddraper
tiny tokens, but needed for every single operation

~~~
3pt14159
Sure, but the really hot tokens could be cached right next to the DB. Plus how
many operations is a person doing per second? If its more than a couple you
can batch them pretty easily.

------
DenisM
IIRC tptacek has been beating this drum for a while, but it seems that he got
tired of it, so I should pick the drum sticks in his stead:

Use less crypto. The less crypto is being used, the fewer mistakes are being
made.

When it comes to sessions, generated a secure random 256 bit token and use
that as a session id. Store it in a database or in-memory store. Sticky
sessions + local session token storage will fix your network latency problems
when you start scaling out.

Federation becomes moderately difficult. Perhaps you could store a copy of
session id on each node, and when a session id is compromised, proactively
reach to all nodes and ask them to purge the session. This allows immediate
mitigation for a session id leak, and since it doesn't rely on timeouts there
is no vulnerability window for data exfiltratiin upon a breach. And no crypto.

~~~
lobster_johnson
This misses one huge benefit of JWTs: Other parties can trust your token if
they were not the ones to sign it.

For example, say client A calls service B, using a token signed by service C.
Previously, we were using randomly generated session keys, which meant B had
to ask C every time. But with JWTs, B can directly verify that the token is
genuine without asking C, because it has C's public key.

We still check with C now and then, but that's because the token auto-expires.
We use a long-lived master token stored in a cookie to generate new short-
lived ones.

~~~
joepie91_
The problem is that you're trying to treat sessions and authorizations as one
and the same thing. They're not.

What kind of services are you envisioning? Direct-to-database services like
Firebase are a horrible idea for a plethora of security-related reasons, and
if you control both service B and C yourself, then you either a) use one-time
authorization tokens for stateless services or b) exchange a one-time
authorization token for a session on a stateful service.

In none of those three cases do you use the token _as_ the session. Tokens are
handed out on a single-use, as-needed basis.

~~~
lobster_johnson
The user does have a session. Tokens are temporary, short-lived
authorizations.

Sessions require a central session store; every request has to go to the
central session store to check the session's validity. Incurring one session
check per API call is bad enough, but when each API call then invokes half a
dozen other APIs, you have a problem. Central session stores don't scale with
distributed architectures.

I've not heard the term "direct-to-database" before, but we've been doing it
for about 6 years, albeit not using Firebase, and it's huge win over the
classic "custom, ad-hoc API per use case" methodology. Exposing a shared data
layer abstraction between microservices is no different than exposing a more
targeted API (i.e. there's conceptually zero difference between "POST
/objects/42" and "POST /users/42"), including as far as security is concerned.

~~~
kalleboo
There was a solution to that situation proposed here[0] where you keep using
session tokens on the user end (so you can still do stuff like revoke
sessions), but convert that to a signed token for all internal API calls.

[0] [http://cryto.net/%7Ejoepie91/blog/2016/06/19/stop-using-
jwt-...](http://cryto.net/%7Ejoepie91/blog/2016/06/19/stop-using-jwt-for-
sessions-part-2-why-your-solution-doesnt-work/)

~~~
lobster_johnson
Thanks. That's pretty much the solution we ended up with, though the article
author doesn't see the whole picture. Asking a central authority to issue
single-use tokens for every call will result in a huge amount of unneeded
network traffic.

------
jordz
Also, worth mentioning this article as an opinion:

[http://cryto.net/~joepie91/blog/2016/06/13/stop-using-jwt-
fo...](http://cryto.net/~joepie91/blog/2016/06/13/stop-using-jwt-for-
sessions/)

Edit: Title is Stop using JWT for sessions

~~~
dang
[https://news.ycombinator.com/item?id=11895440](https://news.ycombinator.com/item?id=11895440)

------
nstart
That last part where he talks about logging out being the responsibility of
the client is rather key. Basically I can't invalidate the key from the server
side. So if a user's account is compromised and they recover it on their
mobile app for example, I can't sign the user out of everywhere else too. It's
what has given me pause about jwt so far and has held me back from using it. I
find the cookie is generally good enough to hold most other information I need
about the user.

~~~
bigonlogn
You can implement sign out everywhere by setting a reauth flag on the user in
the database. You lose the "completely stateless" aspect that JWT claims to
provide, but it's a small trade-off for tighter security.

~~~
tszming
Effectively now you are using database as your session storage?

~~~
dexterdog
But you're not storing the session there, just the key/token so you can change
it. The session payload is still completely in the JSON body maintained by the
client and sent with each request.

~~~
jeremyjh
What difference does that make? Once you commit to this you have to do a
database lookup for every request. Why not keep the session data there?

~~~
dexterdog
You only have to validate the token. It doesn't have to be a database-type
medium because you're not writing very often in fact all you're really doing
is making sure the token is not invalid. The session data could be changing on
every request which would be at least one write on every request. With this
system you are only writing to the central medium on a session creation or a
session invalidation.

~~~
bigonlogn
This is not entirely true. Since we talking about implementing stateful
sessions, you could receive a valid token (stolen, out otherwise) after the
user has logged out.

You are correct that the lookup doesn't have to be via the database. You could
implement a caching system where the cache is invalidated when the user logs
out and requires reauthentication. This is the notion of the session. By
definition they cannot be stateless.

Stateless authentication is inherently (slightly) less secure than sessions. I
think of a blind librarian who gives out keys to the library. Whoever has a
key has access. You can put limitations on the timeframe someone has access to
the library, but that's it. If your key gets stolen, the blind librarian can't
help you as there is no way for him to tell if it's really you.

------
mkagenius
A security note regarding JWTs - [https://auth0.com/blog/2015/03/31/critical-
vulnerabilities-i...](https://auth0.com/blog/2015/03/31/critical-
vulnerabilities-in-json-web-token-libraries/)

~~~
lobster_johnson
That one is from March 2015, and are about some specific libraries that had
vulnerabilities at that time.

------
tootie
If you need to validate the Authorization header on every request that's not
really different than using session tokens we've been using for the past 15
years. JWT is just a formalized way of managing cookies. Which is nice and I
like it, but it doesn't actually enable anything that couldn't be done before
albeit with a more ad hoc approach.

~~~
aleem
Right, Signed Cookies.

JWT doesn't make the claim that it's a new concept, you are assuming as much.
It's a standard and as you correctly gleaned and like most other standards,
comes with a lot of benefits, best practices, is battle tested and ready-to-
use in your favorite frameworks.

It becomes even more useful if you application serves multiple clients such as
browsers, iOS applications and so forth because you can hit the ground running
without having to reinvent anything.

~~~
joepie91_
Both browsers and mobile frameworks can deal with session cookies just fine.
JWT doesn't solve _anything_ there.

------
saynsedit

        [headerB64, payloadB64, signatureB64] = jwt.split('.');
    
        if (atob(signatureB64) === signatureCreatingFunction(headerB64 + '.' + payloadB64) {  
            // good
        } else
            // no good
        }
    

You _really_ need a constant time compare for the signature, else you leak
information about the correct signature in the timing of the response.

~~~
jsmeaton
I don't think this is true. Timing attacks are only really useful if you can
change a single piece of data and analyze the time difference until you find
the right value, over and over again. Like comparing a password.

The unknown data in the signature creating function is a key. The output is a
hash. If you were trying to capture the key you would need to guess what the
key was to get the correct hash. Each byte you change results in a cascade of
changes in the output. You can't get information about the key from a timing
attack on a hash function. I think.

~~~
saynsedit
This is not about retrieving the key, an attacker can still retrieve the
correct opaque signature for specific data. This potentially allows an
attacker to impersonate a user.

~~~
jsmeaton
The signature is already available - it's literally appended to the output.
Verifying the signature is done by hashing the body with a secret (key) and
comparing it to the known signature.

    
    
        "Known" === HMACSHA256(payload, secret)
    

You already know the left hand side. How would a constant time comparison
protect you from a timing attack in this scenario? It wouldn't. The signature
is known, the payload is known, but the secret is not known. That means you'd
have to attack the secret, which you could even do offline. By iteratively
changing the secret, even if you were to get the first half of the hash right,
the next character you change would potentially change every single character
in the output.

JWT/JWS does not concern itself with keeping the token secret or providing
encryption. It's only concern is message authentication. If you leak your
token, someone else can impersonate you, just like if you'd leaked your
session cookie. The only viable attack on the scheme is to brute force (or
discover) the secret, which would allow you to sign a message of your
choosing. Once you can sign a message as if you were the server, then you may
impersonate anyone you choose.

~~~
saynsedit
First, the signature isn't necessary public. As you said, there is a
separation of concerns. If the JWT authentication is wrapped underneath
encryption, then the signature _is_ private.

In either case, public or private, an attacker shouldn't be able to create
their own tokens at their leisure. Token theft is guarded against using
encryption, token creation is guarded against using constant-time compare.
Encryption cannot protect timing attacks.

Again, the hash secret is irrelevant in the case of trying to generate a token
for a specific user. The signature for a specific user payload is an opaque
hash that can be discovered via timing analysis. The secret hash function that
was used to produce it is not important if timing information is available.

If you cannot understand this, please I beg you, do NOT design crypto systems.
If you'd like to be an even better Good Samaritan, please disclose your
identity to the community. This may protect your future employer and their
customers from a breach.

~~~
jsmeaton
> If you cannot understand this, please I beg you, do NOT design crypto
> systems. If you'd like to be an even better Good Samaritan, please disclose
> your identity to the community. This may protect your future employer and
> their customers from a breach.

First let me say that I believed we were having a decent conversation until
this comment right here. You're personally attacking me at this point. I am
_not_ designing crypto. In my first message I stated multiple times that those
were my thoughts. My identity isn't hidden - if you care to look through my
history. Your account is 20 days old, and you're talking to me about making my
identity public?

Anyhow, I now understand the attack you've been describing. I misunderstood
the attack, thinking you wanted to be able to sign any message of your
choosing. Rather, the attack is focused on iteratively changing the signature
of a message until the server confirms it. I was wrong, you were right. The
spec for JSON Web Algorithms (JWA)[0] confirms this.

[0] [https://tools.ietf.org/html/draft-ietf-jose-json-web-
algorit...](https://tools.ietf.org/html/draft-ietf-jose-json-web-
algorithms-40#section-3.2)

~~~
saynsedit
It wasn't a personal attack. Computer security is a minefield of unknown
unknowns. Individuals that aren't deeply familiar with all the modern attacks
or aren't skeptical of unknown attacks shouldn't design crypto, has nothing to
do with you. Some people need a document to tell them what the secure thing to
do is, security analysts don't. I would beg _anyone_ who claims that timing
attacks against signatures don't exist to not build crypto systems. In the
same way I would beg _anyone_ who denies climate change to not make public
policy, wouldn't you?

~~~
jsmeaton
It wasn't the "don't build security" that was the attack. It was "be a good
boy and tell us who you are so we're protected from your incompetence" that
I'm taking issue with.

I think it's particularly unfair seeing as your original reply to me was so
brief that I missed the crucial point. Anyhow, we're done here.

~~~
saynsedit
Asking you to disclose your identity was only a suggestion and it was offered
at your discretion, appealing to your potential desire to be a Good Samaritan.

My sincere intent was not to offend you but protect you from yourself. I had
already offered what I thought was sufficient explanation for the attack and I
felt there were no further options.

I did not mean to offend you but since I have I apologize. I don't believe
one's self-worth or employability is based on their expertise in computer
security but I can see how that can be implied by what I wrote and I was wrong
to be careless with my language online. Honestly I am no expert either. I just
hope we can all cooperate, put our egos aside, remain humble in our limited
knowledge, keep an open mind and stay focused on the facts to build more
secure systems.

Peace and well wishes to you and your family.

------
hit8run
A similar approach are encrypted cookies. You can take data and sign it. The
server can then check if the cookie data is correctly signed and accepts or
rejects the data in the cookie. This approach also scales horizontally. I use
it for a while now in go
([http://www.gorillatoolkit.org/pkg/sessions](http://www.gorillatoolkit.org/pkg/sessions)).
If you want you can also encrypt the expiry date into the secured cookie.

~~~
Xeoncross
Yes, I've been using encrypted cookies for years. If the user wants to use my
website - they can store their own session data.

The trade-off is extra bytes over the wire as the cookie is sent each same-
domain request.

~~~
markdog12
Not if you use HTTP2

------
zatkin
Aren't cookies the safest approach for storing authorization tokens? I
recently found out that both Google and Facebook use cookies for
authorization, so it seems like the way to go, though I've read that it gives
programmer headaches.

~~~
scope
Cookies can be/are used for extensive tracking (even when you're not
_techically_ on the site). The EU requires websites that use cookies to
display conformation message on how cookies will be used to track the user.

~~~
spriggan3
The infamous "cookie" law isn't limited to Cookies. JWT, local storage and co
all fall under the same law that will force you to put a disclaimer on your
webpages. There is absolutely no difference between the 2 in that regard. The
fact that you think otherwise is a serious legal risk for your business if you
have one.

------
palmdeezy
This is the 3rd or 4th article in the last 3 weeks on JWT. Each has argued
that JWT is either secure or totally useless. What is the deal?

~~~
joepie91_
The two are not mutually exclusive. Either way, my article
([http://cryto.net/~joepie91/blog/2016/06/13/stop-using-jwt-
fo...](http://cryto.net/~joepie91/blog/2016/06/13/stop-using-jwt-for-
sessions/)) argues neither.

------
jcoffland
This is a practical implementation of something I described on stackoverflow
in 2013. [http://stackoverflow.com/questions/319530/restful-
authentica...](http://stackoverflow.com/questions/319530/restful-
authentication/19369619#19369619)

The discussion there is rather interesting. The problem of invalidating logins
is discussed. I have not found any satisfactory solution to this problem. You
can set a timeout on tokens but then the user would have to log back in
periodically. If the software can renew the token automatically then there is
nothing to stop an attacker with a stolen token from doing the same,
indefinitely. Still, in many situations these problems are no worse than
compromised session based logins.

~~~
niftich
Serious question: are there any opinionated frameworks that use JWT for
session-like or session-replacing ways?

There was one was linked in this thread [1], but how did framework authors
tackle this domain? Is everything discussed here entirely homegrown, ad-hoc?
Is this something that every one of us has to read up on and re-implement
every time?

[1] [https://github.com/hharnisc/auth-
service](https://github.com/hharnisc/auth-service)

------
carapace
Reminds me of "macaroons".

[http://research.google.com/pubs/pub41892.html](http://research.google.com/pubs/pub41892.html)
"Macaroons: Cookies with Contextual Caveats for Decentralized Authorization in
the Cloud"

~~~
arnarbi
It's unfortunate that the JWT encoding scheme of the signed data (non-
normative JSON -> base64 -> concatenate with a dot) does not lend itself well
to hash-chaining. JWTs could have been a great standard encoding for
macaroons.

(disclaimer: I'm an author of that paper)

~~~
sk5t
Solid point... I suspect many of the shortcuts in JWT (e.g., not making any
attempt to normalize / canonicalize before signing) are a backlash against the
implementation headaches of SAML, specifically XML-DSig and the troubles
associated with "tell me the ID of the signed element and I'll verify it's
signed" mode operation.

------
skybrian
I didn't understand this part:

"if your application maintained a list of key/algorithm pairs, and each of the
pairs had a name (id), you could add that key id to the header and then during
verification of the JWT you would have more confidence in picking the
algorithm"

This implies there's a security benefit, but I don't understand how it's
better than checking the alg parameter against a whitelist. Perhaps if you're
using non-standard names for algorithms, that guards against mistakes?

------
Bino
Why the obsession with 3 letter short names? Why "typ" and not "type". I'm
sore the overhead can be ignored and the parser doesn't care.

~~~
ninkendo
The JWT has to fit inside HTTP headers, which means it's not unlimited in
size. The default header size limit varies by web server, but once you get
above 8k it becomes a game of "which reverse proxy is choking on these headers
this time?".

It's compounded by the fact that a lot of web servers (ie. nginx) have a
global header size that limits all of your headers together, not just any one
header, which means your JWT size limit is nondeterministic, especially if
have large-ish cookies in your request.

There's standard ways to include the JWT in the request body, like form
encoding, but that doesn't work for GET requests, so in practice everyone uses
the Authorization header.

~~~
wtbob
> There's standard ways to include the JWT in the request body, like form
> encoding, but that doesn't work for GET requests, so in practice everyone
> uses the Authorization header.

You can include a JWT as an access_token URL parameter, which works in a GET:

    
    
        https://foo.invalid/bar?access_token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9.TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFONFh7HgQ

~~~
mschuster91
> You can include a JWT as an access_token URL parameter, which works in a
> GET:

Only works with IE > 11, and even IE 11 breaks down sometimes. Also, search
engines choke on large URLs, see
[http://stackoverflow.com/a/417184/1933738](http://stackoverflow.com/a/417184/1933738)

~~~
wtbob
Ummm, every browser for decades has supported URL parameters. I can't believe
that IE breaks with them.

Yes, large URLs are an issue, but not with search engines & access tokens,
since search engines shouldn't ever see access tokens. A JWT should be
lightweight — if it's big, then it's wrong.

~~~
yxhuvud
There are length restrictions for get parameters in older browsers.

~~~
erpellan
Up to 2000 characters is generally considered fine.

------
carsongross
I recently added support for reading/writing localStorage variables in
intercooler.js to support things like this:

[https://github.com/LeadDyno/intercooler-
js/commit/e83a1ff76a...](https://github.com/LeadDyno/intercooler-
js/commit/e83a1ff76a5c3d9c97c2bb63ee707eda1b100496)

------
jcadam
So, I've started working on a new project recently, and thought I'd use JWT
(instead of Ye Olde cookie-based sessions). After working with it for a bit,
I've decided that I can probably get away with using it for authentication,
but definitely NOT for authorization.

I'm using a kind of RBAC and storing Roles in the JWT just seems like a bad
idea. Header size is one issue, but also there is the problem of
granting/revoking a role and having that change reflected immediately (rather
than waiting on the token refresh window).

So, now my API requests happen thusly: "Ok, I have a valid token for User X,
so I accept that this request came from User X. Now, let's check User X's
roles in the database to see if they have permission to perform action Y on
resource Z..."

Hmm... I'm not sure this feels right.

------
moyok
The thing that scares me about using JWT is that all security completely
relies on the one secret that is used to sign tokens - any person with access
to that secret has got potentially unlimited access to the app. They can now
impersonate any user and do basically anything.

~~~
wtbob
Yes, it'd be better if JWTs were full-fledged certificates, where ultimate
authority could be confined to some offline key, who delegates authority for
strictly delimited period to online keys. Or ultimate authority could belong
to k out of a collection of n keys: one would need to suborn k keys to suborn
the authority as a whole.

RFCs 2692 & 2693 specify a really great, lightweight, way to do that. They
resulting certificates needn't be a whole lot heavier than a JWT, and are
_much_ lighter-weight than and X.509 certificate. The RFCs also specify an
intelligent, domain-neutral algorithm for performing calculations on tags
(what JWT refers to as 'claims') and keys.

It's a pretty awesome solution, and there are a lot of good ideas in there. A
streamlined version could, I think, end up being competitive with JWTs.

~~~
iheartmemcache
SPKI was deprecated for SDSI[1] (also done by Rivest), both of which AFAIK
haven't been touched in ~20 years (which is fine by me, if the theory and
implementation are solid, but SDSI has CORBA/J2EE smells all over the RFC from
what I remember. Lightweight, eh...)

[1]
[https://people.csail.mit.edu/rivest/sdsi11.html](https://people.csail.mit.edu/rivest/sdsi11.html)

~~~
wtbob
> SPKI was deprecated for SDSI

No, it's the other way around: SDSI was deprecated for SPKI, which took a lot
of its ideas about naming from SDSI.

> both of which AFAIK haven't been touched in ~20 years (which is fine by me,
> if the theory and implementation are solid, but SDSI has CORBA/J2EE smells
> all over the RFC from what I remember. Lightweight, eh...)

SPKI is indeed old, but the fundamental ideas are really good, and some of
them (the cert calculus) are timeless. It needs a v2.0 to update the
recommended crypto, specify some more use cases and so forth. But it's really,
_really_ good, far better than XPKI and extremely capable.

And still pretty lightweight.

~~~
iheartmemcache
Hey, if the conceptual grounds are sound, which I'm guessing they are,
since... I mean, Ron Rivest, age doesn't quite matter w/r/t the timeless
elements. Rijndael is mathematically sound, and honestly I've got more trust
in older algorithms than newer ones if only because there's been more time for
the populace to vet it[1] presumably fortifying it with time.

All of the resources I've searched for are fairly old, do you have anything
more recent that I can read up on? I see a 2006 paper, but not much other than
that.

[1] Though I'm well aware that having an open-standard available for a _long
time_ doesn't mean squat, as evidenced by Heartbleed-esque bugs.

Edit: Reading the '00 "A Formal Semantics for SPKI" Howell, Katz, Dartmouth.
This is what I was looking for.

~~~
wtbob
I wonder what you think so far.

In particular, I liked the tuple-calculus they define; it can be extended to
support just about any permission I can think of (although it does require
reversing DNS names, which is slightly ugly).

I have a scheme to release a v2.0 of the standard someday in my copious free
time.

------
stephenr
I've had this "them: we should use JWT, it's easier to scale; me: the customer
has 200 clients, they don't need to scale shit, sessions are fine" argument
before, and honestly at this point I'm pretty convinced JWT isn't a
replacement for session auth.

The one place I can see it _might_ be useful, is when you need to give a
third-party system some kind of access to your API, as an alternative to
storing a secondary hashed field(s) for api keys.

------
spriggan3
A few years later : "JWT in place of sessions considered harmful".

------
hharnisch
JWT is especially useful for validating requests in a microservice
architecture. You can pass around the token an embed roles in them. No need to
keep a session store with them!

~~~
hharnisch
On another note I've been working on a service that generates
expirable/refreshable JWTs. Its a good way to start trying them out
[https://github.com/hharnisc/auth-service](https://github.com/hharnisc/auth-
service)

~~~
joepie91_
Better remove that again. It is _extremely dangerous_ to store _any_ kind of
credential in Local Storage. Cookies are the (only) correct place for storing
credentials.

~~~
areed
Because you can set Secure and HttpOnly flags on cookies? This merely brings
them up to the same level of security you get with Local Storage.
[http://blog.portswigger.net/2016/05/web-storage-lesser-
evil-...](http://blog.portswigger.net/2016/05/web-storage-lesser-evil-for-
session.html)

~~~
pags
What is a "level" of security? If I'm able to inject arbitrary code into your
page, with it I can access your local storage data, but I can't access your
"http only" cookies - so there's at least some "level" of difference.

~~~
garfij
If you're at the point where someone can inject random code into your site,
you've already lost and have so many more problems than access to
localStorage.

------
smaili
Correct me if I'm wrong but the benefits sound very similar to a good old
fashion cookie except that you're not limited by 4kb.

~~~
Negative1
This is the common misconception. Think of a cookie as a storage 'bucket' on a
user's device. It can store up to 4KB in bytes of, well, anything (a string).
JWT is format. That's it. It is enciphered and has the ability to store JSON,
but otherwise, it's just a format or scheme that allows you to organize how
you store your session (or whatever) data. As an example, in my usage I
actually store my JWT in a user cookie and all it keeps is the expiration,
user id and a few other tidbits I don't want to hit a database for but am
comfortable exposing in case the token is cracked.

~~~
ekryski
I agree that's how we treat them with Feathers. You may know this already but
JWT's are intended to be decrypted on the client so you shouldn't be be saying
"if" it is cracked, more "when". The signature is only good for ensuring that
the content hasn't been manipulated. Not that you are, but for others, never
store anything inside a JWT that is sensitive, and if it is make sure you
encrypt it first before you put it in the JWT payload.

------
erpellan
The assertion that cookies require server state is wrong. A JWT would easily
fit inside a cookie. Or a URL for that matter.

------
geuis
How does this avoid the problem of a 3rd party getting your jwt token? Then
they can do any request as you.

~~~
intrasight
Tying the token to an IP address will largely ameliorate that issue. As
always, there is a tradeoff of security and convenience. I've worked at
facilities with no internet access, where hard drives were removed and put in
safes at the end of the day, and that had "leper lights" which flashed when
unsecure people like me were present. Very secure but hardly convenient. You
always need to ask yourself what it is that you are securing.

~~~
levelist_com
You should not tie any functionality, user experience, and last but certainly
not least, security to an IP address. IP addresses can be spoofed rather
easily, using public wifi, hotel/guest networks, and even certain ISPs means
the rotating of IP addresses on each user request.

~~~
intrasight
Adding an IP lock to a token can only increase security - it cannot decrease
security. And if you wish to be secure, then you wouldn't use public wifi.

~~~
levelist_com
What you're doing is increasing complexity, even if marginal, for no benefit
and to the inconvenience of your users; Sometimes, increased complexity does
introduce insecurities, but I digress. The developer has little to no control
over what type of network (wi-fi, public hotspot, hotel, corporate, private,
etc..) a user accesses the site with and the user couldn't care less how
sessions are managed (for the most part), all they know is if their token
becomes invalid on each request because they are using a network that pools
and rotates IP addresses b/w users/requests, forcing them to re-authenticate
with each request, well, you're going to have some very unhappy users.

~~~
intrasight
Most enterprise application users who are working are unhappy users. I'm not
trying to fix that problem.

------
blazespin
jwt are the capability model. They are not forgeable and they expire. You can
revoke them by telling the database to ignore them by the token id. If you
have a services based model you can pass them along and they can verify your
capability without going to the db.

------
ams6110
Functionally, sounds a lot like http basic authentication, only more
complicated.

------
davb
XHR? Sessions.

REST? Bearer tokens or OAuth.

Third party trust? JWT.

------
tszming
People don't realize it is not a proper comparison as JWT is only the
format/spec - you can still achieve stateless client session by encrypting an
XML payload (e.g. user id) in the browser cookie. Storing data in client and
verify by signature is not a new thing.

------
lukeh
Ah, Kerberos :-)

