A Complete Guide to JSON Web Token (JWT)

26 Oct, 2019

JWT is an open standard for creating compact and self-contained JSON-based object for transmitting an assertion between parties

JSON Web Token (JWT) is an open standard for creating compact and self-contained JSON-based object that assert some number of claims, being used at scale, easier to process on any kind devices, great for authorization, secure for transmitting data between multiple parties.

Motivation

Before JWT, for the purpose of authentication/authorization and data exchange between multiple parties, we could use Simple Web Token or Security Assertion Markup Language.

Simple Web Token (SWT) is a format for transmitting an assertion between two parties, the assertion is a set of name/value pairs that have been HTML form encoded and then the resulting string is asserted by a SHA 256 HMAC using a key shared between the parties.

Security Assertion Markup Language (SAML) is an XML-based markup language for security assertions, consists of a set of XML-based protocol messages, a set of protocol message bindings and a set of profiles.

Compared to above SWT and SAML, JWT has following benefits:

  • Encoded JWT is more compact than SAML
  • JSON-based JWT is less verbose than XML-based SAML
  • JSON parsers are common in most programming languages
  • JWT can be processed easily at scale on multiple client platforms
  • JWT can be verified and trusted because it is digitally signed
  • JWT is URL safe, easy to pass around via URL parameters
  • JWT is security wise when it can be signed using a secret (with the HMAC algorithm) or a public/private key pair using RSA or ECDSA.
  • JWT is self-contained, so it's convenient for embedding information and reducing the need to query the database multiple times
  • JWT is stateless by design, so we don’t have to fight with stateless design of HTTP

Structure

JWT consists three parts -- header, payload, signature -- separated by dot (.) and typically looks like this xxxxx.yyyyy.zzzzz

Header -- consists the type of token and the cryptographic algorithms

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

Payload -- consists the claims which are statements about an entity and additional data, you can use register claims or custom claims.

{
  "sub": "1234567890",
  "name": "Hoang Nguyen",
  "iat": 1516239022
}

Signature -- to create the signature part you have to take the encoded header, the encoded payload, a secret, the algorithm specified in the header, and sign that.

HMACSHA256(
  base64UrlEncode(header) + '.' + base64UrlEncode(payload),
  'your-256-bit-secret'
)

Putting all above together, we'll have following JWT which is three Base64-URL strings separated by dots that can be easily passed in HTML and HTTP environments.

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkhvYW5nIE5ndXllbiIsImlhdCI6MTUxNjIzOTAyMn0.Z7dCrbAxqyg5QPNtvEcQg5CAB6mvhU7UgI_oUvIFtzU

Use Cases

Using JWT for Authentication is such a common use case -- The application server can be completely stateless, as there is no need to keep tokens in-memory between requests. The authentication server can issue the token, send it back and then immediately discard it!

JWT is also a good way of securely transmitting information between parties -- JWT can be signed using public/private key pairs so you can be sure the senders are who they say they are. As the signature is calculated using the header and the payload, you can also verify that the content hasn't been tampered with.

Best Practices

Keep JWT safe and secret, also treat signing key like any other credentials and revealed only to services that need it.

Do not add sensitive data to the payload. JWT is signed to protect against manipulation and is easily decoded. Add the bare minimum number of claims to the payload for best performance and security.

Give tokens an expiration. Technically, once a token is signed – it is valid forever – unless the signing key is changed or expiration explicitly set. This could pose potential issues so have a strategy for expiring and/or revoking tokens.

JWT is a great technology for API authentication and server-to-server authorization. It’s not a good choice for sessions.

JWT may contain session state. But if project requirements allow session invalidation before JWT expiration, services can no longer trust token assertions by the token alone. To validate the session stored in the token is not revoked, token assertions must be checked against a data store. This renders the tokens no longer stateless, undermining the primary advantage of JWT.

Make sure you know when it’s best used, when it’s best to use something else, and how to prevent the most basic security issues.

Reading More


Same series:

Tech Explained