How JWT (JSON Web Token) authentication works?
What is JWT (JSON Web Token)?
JSON Web Token (JWT) is an open standard (RFC 7519) for securely transmitting information between parties as JSON object.
It is compact, readable and digitally signed using a private key/ or a public key pair by the Identity Provider(IdP). So the integrity and authenticity of the token can be verified by other parties involved.
The purpose of using JWT is not to hide data but to ensure the authenticity of the data. JWT is signed and encoded, not encrypted.
JWT is a token based stateless authentication mechanism. Since it is a client-side based stateless session, server doesn't have to completely rely on a datastore(database) to save session information.
Structure of JWT
A JSON Web Token consists of 3 parts separated by a period.
header.payload.signature
Header
JWT header consists of token type and algorithm used for signing and encoding. Algorithms can be HMAC, SHA256, RSA, HS256 or RS256.
{
"typ": "JWT",
"alg": "HS256"
}
Payload
Payload consists of the session data called as claims. Below are some of the the standard claims that we can use,
- Issuer(iss)
- Subject (sub)
- Audience (aud)
- Expiration time (exp)
- Issued at (iat)
{
"sub": "user10001",
"iat": 1569302116
}
Custom claims can also be included in the claim set. When using custom claim sets,
- Do not put large data in claim sets. Claim sets meant to be compact.
- Do not put sensitive informations since, JWT can be decoded easily.
{
"sub": "user10001",
"iat": 1569302116,
"role": "admin",
"user_id": "user10001"
}
Signature
Signature is most important part of a JSON Web Token(JWT). Signature is calculated by encoding the header and payload using Base64url Encoding and concatenating them with a period separator. Which is then given to the cryptographic algorithm.
// signature algorithm
data = base64urlEncode( header ) + "." + base64urlEncode( payload )
signature = HMAC-SHA256( data, secret_salt )
So when the header or payload changes, signature has to calculated again. Only the Identity Provider(IdP) has the private key to calculate the signature which prevents the tampering of token.
How it works?
Basically the identity provider(IdP) generates a JWT certifying user identity and Resource server decodes and verifies the authenticity of the token using secret salt / public key.
- User sign-in using username and password or google/facebook.
- Authentication server verifies the credentials and issues a jwt signed using either a secret salt or a private key.
- User's Client uses the JWT to access protected resources by passing the JWT in HTTP Authorization header.
- Resource server then verifies the authenticity of the token using the secret salt/ public key.
Security
Just like any other authentication mechanism, JWT also has its own pros and cons.
- Must use HTTPS to secure the Authorization headers.
- Validate algorithm name explicitly. Do not completely rely on the algorithm mentioned in the header of JWT. There are a few known attacks based on the header like algo none attack, header stripping.
- Revoking the session of a user from backend server is difficult. Since a JWT is set to automatically expire, If an attacker gets the token before it expires It leads to various exploits. Building a token revocation list on your server to invalidate tokens could be best way to mitigate.
- If JWT is persisted on cookies, we need to create HttpOnly cookie. This will restrict third party javascripts from reading jwt token from cookie.
- XSS - backend servers must always sanitize user generated data.
- CSRF - If JWT in persisted on cookies, CSRF attacks are possible. We can mitigate CSRF by using origin of request and special request headers.