
How to Use JSON Web Tokens - ristem
https://github.com/dwyl/learn-json-web-tokens/blob/master/README.md
======
KaiserPro
JWTs are useful, but there are a few things that are not immediately obvious.

1) They are _signed_ not encrypted. Anything you put in there is public
readable, _unless you encrypt your token after you generate it_

2) you can accept a range of encryption types, don't. Stick to one type and
disallow any token that doesn't conform (this protects against people making
their own tokens with 'None' as the signing algorithm)

I am surprised at how naive the JWT spec is. Why in this day an age is
encryption a default for the _payload_? Also, why on earth is 'None' allowed
as a signing algorithm? Thats just a cookie..

~~~
mattferderer
> 1) They are signed not encrypted. Anything you put in there is public
> readable, unless you encrypt your token after you generate it

Not a JWT expert but isn't this the point of a JWT or am I missing something.
Sharing data between servers & clients while being able to make sure the data
wasn't changed.

> 2) you can accept a range of encryption types, don't. Stick to one type and
> disallow any token that doesn't conform (this protects against people making
> their own tokens with 'None' as the signing algorithm)

People do this?? Why?

~~~
smadge
> Sharing data between servers & clients while being able to make sure the
> data wasn't changed.

I think the main use is sharing data between the server and itself. The client
shouldn’t depend on the internal structure of the token. The token should just
be issued by the server to the client, and the client passes it along to
subsequent requests to the server.

~~~
mattferderer
Both good points!

------
michelpp
This is a good Javascript-centric writeup. This caught my eye thought:

> Since JSON Web Tokens (JWT) are not signed using asymmetric encryption ...

You don't have to, but can of course sign your JWTs with asymmetric keys, and
many libraries support this. Third party token issuers (firebase, google,
auth0) require asymmetric, since they're clearly not going to share a secret
with you.

Asymmetric also provides two-way token verification: The issuer signs the
token with a private key, and receivers of the token can then verify that the
token is legitimate using the issuers "well-known" public key.

~~~
gregmac
I've dealt with and used JWTs in a few different applications, and all of them
have used assymetric keys, and used as tokens passed between different
systems. Keeping the private key only on the issuing system is more secure (or
even essential, depending on what you're doing).

If you're authenticating on the same system, you could get away with
symmetric, but then the use of JWTs may no longer make sense vs just using a
random key stored persistently on the server (eg, for session cookie,
"remember me" or "forgot password" token) -- I actually can't think of a case
where using JWTs makes sense if you have access to persistent storage. By
storing the random value you can also revoke it server side, which you can't
do normally do with JWTs.

------
TekMol
At first JWTs look cool because you can log in users without managing session
data on the server.

Then you think about how a user can actively log out.

Then you add session management to your server but call it 'token
invalidation'.

~~~
andrewstuart2
This is a problem you have with _any_ federated token-based identity solution.
Distributed logout is a hard problem which can basically be reduced to cache
invalidation (insert N/N-1 hard things in CS joke here).

~~~
tptacek
This is a little like saying "this is a problem you have with ANY identity
solution that looks like JWT". Yes, that's true. The reason people complain
about JWT is that (a) it's the most popular solution of this shape, and (b)
people use it without understanding why they're using it or whether the
tradeoffs work for their application. They usually do not.

Witness everyone saying that the important feature of JWT is that it's
standard and interoperable, as if that was a mandatory feature of most token-
based authentication schemes; in fact, the "portability" of JWT is a security
_liability_ for --- I'll hazard --- the overwhelming majority of applications.

~~~
andrewstuart2
Would you say then that confidentiality is always preferable to availability?
I'm not quite sure how you'd achieve any sort of high availability over time
without interoperability at some level. Presumably, if it has _any_ place,
that interoperability would belong at the lowest level of a protocol stack,
with each successive level tuning acceptable parameters for their application.

~~~
tptacek
I don't understand this question. I don't think it's very common in real-world
applications to deliberately trade confidentiality for extra availability,
though negligently and subtextually making that trade is endemic to our
industry.

~~~
andrewstuart2
I just mean availability in the sense of client support across time as
protocol versions increase, like TLS version negotiation and how it enables
the gradual rather than immediate dropping of server support for clients on
older versions of a spec. Or for example, allowing 2048 bit keys for a time to
allow migration to stronger keys.

Without negotiation, you'd have to stop serving clients that haven't upgraded
at the cutover time.

------
sjroot
This page doesn’t have any discussion of strategies for expiring JWT, one of
the biggest security issues with this auth mechanism. Even the code sample
doesn’t include an expiration.

~~~
redbeard0x0a
The JWT has a built-in field called exp, which is the time the token is
expired. This is built in.

However if you need to 'expire' a JWT token early, there isn't a good way to
do it. If your token has a JTI, then you could add a blacklist for that JTI
(say in redis, with a TTL until the token's exp time). But that is left to the
implementor.

~~~
incadenza
My issue here is that expiring JWTs involve adding state! The whole point of
JWTs is stateless authentication, so I’ve never understood the advantage over
sessions unless revoking tokens is never an option.

~~~
hinkley
When are you expiring tokens ahead of their natural expiration date? When
someone logs out?

Isn’t that state? If you add state to something stateless you are generally on
your own.

[edit: also I disagree with the notion that something with an expiration date
is stateless. It has two states. It’s just that the look like idenpotence]

~~~
iamwil
When someone's account is compromised, is another situation.

~~~
geezerjay
> When someone's account is compromised, is another situation.

Why is that scenario relevant if tokens are supposed to be used once per
request and short-lived?

Once a token is used, it's supposed to be expired and no longer in use. Both
the expiry timestamp and the nonce fields already handle those use cases.

~~~
iamwil
Suppose to be once per request and short-lived. But that's not specified in
the thread above.

Previous person mentioned logout, so I assumed we were talking about session
tokens--which I understand its a misuse of JWTs--and is why he/she's
mentioning it.

But if we're talking about just one time auth tokens, then yeah, you don't
need expiry ahead of the expiry time, and it's plain it's a non-issue.

------
jondubois
I think storing JWTs might make sense for some advanced scenarios where you
have multiple services with varying security requirements but when you store
JWTs, you lose a lot of the benefits of having a stateless token which doesn't
require a database lookup.

A possible alternative is to just make the JWT expiry very short; like one
hour; then you don't really need to explicitly invalidate the token.

With a real time bidirectional transport like WebSockets, you can make the JWT
expiry even shorter; like 10 minutes and you can auto refresh it by pushing a
replacement token to clients every 8 minutes or so. If the expiry is so short,
you don't need the ability to invalidate tokens.

Getting your laptop stolen while you are logged into a service which relies on
JWT is like getting your credit card stolen; it will probably take at least 10
minutes for you call your bank to disable it.

~~~
groestl
An hour could be much much too long, depending on what service you are
protecting. It's long enough that even assuming that token theft is a non-
stealthy operation, and the user reacts immediately, the attacker has a lot of
time to execute his attack. For things like Facebook, this could include
slowly scaping all user data and spreading the infection vector to other
users.

As for websockets: session integrity is handled by TLS, and invalidation can
be handled by closing the TCP connection. Authentication needs to happen only
once, on connect.

~~~
jondubois
Storing JWTs in a store or DB is difficult because you need to manage them and
that means accounting for all possible edge cases. You can't always detect
when a WebSocket/TCP connection has closed from the back end. For example, if
your WebSocket server crashes suddenly, all active JWTs that you keep in your
external data store will be orphaned and they won't get cleaned up until you
run a separate cron job (which adds a lot of complexity).

Storing JWTs in a hashmap in memory is also not ideal if you have multiple
processes/servers because it doesn't account for WebSocket lost connection and
reconnection edge cases; the client could reconnect to a different
server/process than before.

------
kevinburke
Last year I helped several different companies switch off of JWT onto JSON
encrypted with secretbox, which was much more appropriate for their use
case(s). No risk of accidentally using an insecure algorithm or sending secure
data unencrypted to the client.

Local storage is not secure.

------
superasn
One of the biggest advantages of JWT is that is saves up on database reads
which can be significant when you have million+ logged in users.

I think that is probably thinking of time when you had to do everything
yourself (host your own mysql server, create indexes, cache, etc). Now you can
easily save your sessions using stuff like DynamoDb.. it costs almost nothing
and read times are blazing fast even when there are millions of rows. Doesn't
make a lot of sense to use JWT after this.

~~~
amenod
> Now you can easily save your sessions...

True.

> ...using stuff like DynamoDb..

Well, yeah, if you want to be tied to AWS and use a difficult to manage
technology which is only useful in a few niche cases, DynamoDB is absolutely
the right choice </sarcasm>. Otherwise Redis, Memcache or even Postgres would
be a better choice. After all, session management is only a (small) part of
data persistence problem.

~~~
superasn
Yes of course. That was not my point DynamoDb was just something off the top
of my head. You can easily use redis or even any nosql db for that. My point
was about the main advantages of JWT being fast with millions of users isn't
really that big deal anymore.

~~~
amenod
Cool, sorry if I jumped the gun... I recently had to deal with some SW using
DynamoDB for no special reason, so I'm a bit touchy about it. :)

------
endiangroup
A small Go library we wrote to centrally manage distributed session tokens
such as JWT inspired by CAS:
[https://github.com/endiangroup/compandauth](https://github.com/endiangroup/compandauth).
Main highlight is central revocation, locking and unlocking of distributed
sessions

The core concepts can be translated into any language that supports integers,
happy to reference any alternative implementations.

------
danesparza
There are other ways to pass claims -- like using bearer tokens in the HTTP
header, or using OAuth 2. (All with TLS, of course)

~~~
sprt
Yes, JWTs don't bring anything new to the table. In fact, most articles
promoting their use don't even explain _why_ you should use them. This is
cargo cult programming at its utmost.

~~~
orf
There are many ways to do many things. That doesn't make it cargo cult
programming.

Encoding your claims as a JWT is useful because there are many libraries that
work with this, it's a known format (and one that's not tied to any particular
transport), and is really good for creating stateless authentication systems
using asymmetric keys.

If you're interested in the differences between JWTs and something like OAuth
(which really are two different things entirely) then you can visit
[https://google.com](https://google.com) and type in "JWT vs Oauth2". Answers
will appear on your screen.

------
EGreg
I used to just follow whatever people said in oAuth and oAuth 2. No longer.
Once I started questioning why we need all these tokens, when we will anyway
have to look up access information in some database, I got pretty much no
satisfying answers:

[https://security.stackexchange.com/questions/161734/why-
does...](https://security.stackexchange.com/questions/161734/why-does-oauth-
and-oauth-2-have-access-tokens-at-all)

The token may as well just be an AUTENTICATION token, such as the app’s id
with timestamp signed with the shared secret. (Or even better, an asymmetric
private key, where the shared secret is replaced by TWO keypairs, one from
app-to-platform and one from platform-to-app.)

Then you use this app id to look things up in an Access Control List (ACL).

Then stuff becomes easy. Forget all the oAuth crap. The app is just another
user with an ID in your system. Users may grant access to other users, for
different streams of data. The access can have various read/write/admin levels
etc. It can be changed anytime. Finally, users can have LABELS (or Roles)
which determine in one fell swoop what an app can do. That is similar to
“scopes” in oAuth.

I don’t just talk about it — this is how we handle it in our platform:

[https://qbix.com/platform/guide/access](https://qbix.com/platform/guide/access)

------
Dowwie
JWTs are radioactive. Proceed with caution.

~~~
fastbeef
I keep hearing this. Is there a good writeup available?

~~~
tstieff
The parent comment isn't very helpful, but from what I understand people
dislike JWTs because it makes it hard to invalidate a session without some
sort of work-around. For example, you can use 2 tokens, one short lived, and
one long lived to get around the invalidation problem, but then you will need
to occasionally validate that both tokens are still valid, and that state
needs to be stored, and now you're storing some state, which is semi-
contradictory to the purpose of a stateless-token. Here's a more detailed
write-up from another poster --
[https://news.ycombinator.com/item?id=12332119](https://news.ycombinator.com/item?id=12332119)

~~~
jayd16
Isn't that basically oauth?

~~~
StevePerkins
Yes. In a web setting (the most common use case for JWT), they are typically
issued during an oauth dance.

------
B-Con
> Note: Yes, both these methods are synchronous. But, given that neither of
> these methods require any I/O orNetwork requests, its pretty safe to compute
> them synchronously.

Found this amusing. Are node devs so used to async that disclaimers like this
are necessary?

~~~
kevinburke
yes, Node is single threaded so any one thread that blocks the event loop for
a significant amount of time becomes a significant performance bottleneck.
Generally functions like bcrypt require an asynchronous API.

------
firemelt
Is it safe to put jwt in local storage?

------
ape4
Maybe in 2019 we'll stop using JSON/JS for everything

~~~
java_script
Your wish has been granted. 2019 is the year of YAML as a serialization format
and the return of CoffeeScript.

Disclaimer: I am a genie.

~~~
andybak
Can we go back further and have Django/Rails as the new hotness with
Pjax/Turbolinks for the extra cool kids?

