JWT

JSON Web Tokens - jwt.io

Usually used as Access Token for Authorisation not authentication

Components

Have 3 parts separated by .

An example of a JWT token:

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c

Header part

The first part eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9 is Base64 encoded, contains a few headers like the hashing algorithm and the type of it:

{"alg":"HS256","typ":"JWT"}

Body part

The second part is eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ which is also Base64 encrypted:

{ 
	"sub": "1234567890",
	"name": "John Doe", 
	"iat": 1516239022 
}

Mandatory fields

  • sub: is the user id
  • iat: issued time stamp

We can use iat to determine the expired timestamp.

Signature part

The third part is SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c which is the HS256 (declared in the first part) — which is the hash of the first 2 parts to make sure that the values were not modified.

HMACSHA256(
  base64UrlEncode(header) + "." +
  base64UrlEncode(payload),
  <256-secret>
) 

We normally use this with a custom secretKey and we can verify this hash on the serverside to see if it's authentic hash.

Java

Generate a token for example

SessionUserAuthenticationDTO authenticationDTO = new SessionUserAuthenticationDTO("admin", "admin");  
String token = authenticationService.authenticate(authenticationDTO)
DecodedJWT decodedJWT = authenticationService.validate(token);
assertEquals("admin", decodedJWT.getClaim("username").asString());

The code of authenticate and validate could be

@Override  
public String authenticate(SessionUserAuthenticationDTO userAuthenticationDTO) {  
    if (userAuthenticationDTO == null) {  
        return null;  
    }  
    return JWT.create()  
        .withSubject(UUID.randomUUID().toString())  
        .withIssuer("localhost")  
        .withClaim("username", userAuthenticationDTO.username)  
        .withClaim("type", "access")  
        .sign(this.algorithm);  
}  
  
@Override  
public DecodedJWT validate(String token) {  
    JWTVerifier verifier = JWT.require(this.algorithm).withIssuer("localhost").build();  
    return verifier.verify(token);  
}