What is JwtToken (JSON Web Token) and how does it differ from an older concept of a cookie?
On Stack-Overflow I saw a couple of questions about "JwtToken vs Cookie” or "JwtToken instead of Cookie". The fact is, JwtToken is not a direct alternative of a cookie, but rather of a SessionId. What does it exactly mean? It means, you can store the JwtToken in a cookie, just like you would store a SessionId.
The below image shows a JwtToken stored in a cookie named "access_token":
The advantage of a JwtToken over a SessionId is that JwtToken has a built-in validation mechanism. For example when validating the token in your backend, you can check whether it has been tampered with.
Also you can store user id in the token itself. The most important advantage is JwtTokens are stateless, since they contain all the necessary info for validation, so you don't need to store them in a db, like SessionId. Whereas sessionIds need to be stored so they can be later validated. This is especially useful when you have distributed systems where nodes don’t necessarily share a db or some other storage.
There are some UX standards that define expiration times for both JwtToken and cookie. As always, there is a tradeoff here between user convenience and security. Standard is to set JwtToken validity to a week, while refreshing the JwtToken and prolonging the validity every 15 minutes or so. The reason for refreshing token is to refresh the access rights attached to the token frequently in case they change.
Important note here: anyone who has a JwtToken can actually decrypt it online on https://jwt.io/. So, make sure NOT to store any sensitive data inside JwtToken. Because if user’s password is stored in a JwtToken and a hacker would steal it, they wouldn’t only steal user’s session, but also the credentials.
The token below, contains email address, issued-at and expiration dates, which you can read from the decoded payload on the right:
Also using JwtToken might become a disadvantage if you store a lot of data inside it. Since it’s sent back and forth with every request, it can slow down the communication, whereas with the sessionId you are just sending an Id and looking up the data on the server side, which makes the transfer over the network faster.
It’s also important to get some wording about the token type straight:
Long-lived (refresh) token is to prove your authentication: you are a valid user. Short-lived (access) token is there to prove your authorization: your valid user has certain access rights.
This means, the long-lived token needs to be refreshed when you change your password, username or log in again, since you will need to re-prove your authentication. Whereas upgrade to premium membership should lead to refreshing short-lived token, since the user now has more access rights and thus the authorization has changed. However, If you have a mechanism in your application that validates your access to premium features without relying on JwtToken, than you won’t have to refresh the token for that particular case.
But generally, you will have to refresh both short and long lived tokens to make sure they are invalidated after some time, so that if someone stole it, they could not use it with the old authentication or authorization data.