A JSON Web Token (JWT), pronounced ‘jot’, is an open standard (RFC 7519) which is used for securely transmitting information between entities as a JSON object.
JWT is an authentication standard that works by assigning and passing around an encrypted token in requests that helps identify the logged in user instead of storing the user in a session on the server and creating a cookie.
this simply means that a new request made to the server, does not remember anything about the request made before it, the downside of this is that you have to keep querying the db and check the logged in user, you can use session storage as an alternative, but that's a lot of work
a wild token appears
- Assume that we has a website which works well with Session. One day, we want to implement system for Mobile (Native Apps) and use the same Database with the current Web app. What should we do? We cannot authenticate users who use Native App using Session-based Authentication because these kinds don’t have Cookie.
Scalability : The sessions need to be stored on the server, either in memory or in a database. In the current API era, a server can receive a large number of requests, and hence the server needs to be scaled up. Adding new resources can increase the complexity of the infrastructure as well.
all hail the jwt authorization
You can see that it’s simple to understand. Instead of creating a Session, the Server generated a JWT from user login data and send it to the Client. The Client saves the JWT and from now, every Request from Client should be attached that JWT (commonly at header). The Server will validate the JWT and return the Response.
For storing JWT on Client side, it depends on the platform you use:
- HEADER
- PAYLOAD
- SIGNATURE
the header answers the question: How will we calculate JWT, look at an example of header, it’s a JSON object like this:
{ "typ": "JWT", "alg": "HS256" }
– typ is ‘type’, indicates that Token type here is JWT.
– alg stands for ‘algorithm’ which is a hash algorithm for generating Token signature. In the code above, HS256 is HMAC-SHA256 – the algorithm which uses Secret Key.
The Payload helps us to answer: What do we want to store in JWT?
This is a payload sample:
{
"userId": "abcd12345ghijk",
"username": "th3realad",
"email": "contact@th3realad.com",
// standard fields
"iss": "th3realad",
"iat": 1570238918,
"exp": 1570238992
}
In the previous JSON object , we store 3 user fields: userId, username, email. You can save any field you want.
We also have some Standart Fields. They are optional.
This is where we use the Hash Algorithm that I told you about
Look at the code for getting the Signature below:
const data = Base64UrlEncode(header) + '.' + Base64UrlEncode(payload);
const hashedData = Hash(data, secret);
const signature = Base64UrlEncode(hashedData);
– First, we encode Header and Payload, join them with a dot .
– Next, we make a hash of the data using Hash algorithm (defined at Header) with a secret string.
– Finally, we encode the hashing result to get Signature.
After having Header, Payload, Signature, we’re gonna combine them into JWT standard structure: header.payload.signature, which results into something like this:
eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VySWQiOiJhYmNkMTIzNDVnaGlqayIsInVzZXJuYW1lIjoiYmV6a29kZXIiLCJlbWFpbCI6ImNvbnRhY3RAYmV6a29kZXIuY29tIn0.5IN4qmZTS3LEaXCisfJQhrSyhSPXEgM1ux-qXsGKacQ
JWT does not hide, obscure, secure data at all. You can see that the process of generating JWT (Header, Payload, Signature) only encode & hash data, not encrypt data.
The purpose of JWT is to prove that the data is generated by an authentic source.
So, what if there is a Man-in-the-middle attack that can get JWT, then decode user information? Yes, that is possible, so always make sure that your application has the HTTPS encryption.
we use a Secret string to create Signature. This Secret string is unique for every Application and must be stored securely in the server side.
When receiving JWT from Client, the Server gets the Signature, verify that the Signature is correctly hashed by the same algorithm and Secret string as above. If it matches the Server’s signature, the JWT is valid, We also store the Token before sending it to the Client. It can ensure that the JWT transmitted later by the Client is valid.
There will never be a best method for authentication. It depends on the use case and how you want to implement.
However, for apps that you want to scale to a large number of users across many platforms, JWT Authentication is preferred.