JSON Web Token
JSON Web Token
is a proposed Internet standard for creating data with optional signature and/or optional encryption whose payload holds JSON that asserts some number of claims. The tokens are signed either using a private secret or a public/private key.
For example, a server could generate a token that has the claim "logged in as administrator" and provide that to a client. The client could then use that token to prove that it is logged in as admin. The tokens can be signed by one party's private key so that any party can subsequently verify whether the token is legitimate. If the other party, by some suitable and trustworthy means, is in possession of the corresponding public key, they too are able to verify the token's legitimacy. The tokens are designed to be compact, URL-safe, and usable, especially in a web-browser single-sign-on context. JWT claims can typically be used to pass identity of authenticated users between an identity provider and a service provider, or any other type of claims as required by business processes.
JWT relies on other JSON-based standards: JSON Web Signature and JSON Web Encryption.
Structure
;Header;Payload
;Signature
HMAC_SHA256 + '.' +
base64urlEncoding
The three are encoded separately using Base64url Encoding, and concatenated using periods to produce the JWT:
const token: string = base64urlEncoding + '.' + base64urlEncoding + '.' + base64urlEncoding
The above data and the secret of "secretkey" creates the token:
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJsb2dnZWRJbkFzIjoiYWRtaW4iLCJpYXQiOjE0MjI3Nzk2Mzh9.gzSraSYS8EXBxLN
_oWnFSRgCzcmJmMjLiuyu5CSpyHIThis resulting token can be easily passed into HTML and HTTP.
Use
In authentication, when a user successfully logs in, a JSON Web Token is often returned. This token should be sent to the client using a secure mechanism like an HTTP-only cookie. Storing the JWT locally in browser storage mechanisms like local or session storage is discouraged. This is because JavaScript running on the client-side can access these storage mechanisms, exposing the JWT and compromising security. To make use of the HTTP-only cookie, as you might need it to authenticate with cross-origin APIs, the best approach is to use the credentials property to tell the browser to automatically send the cookies to the external APIs via a Fetch call like so:fetch
.then)
.then
.catch;
By using this method, the JWT is never exposed to client-side JavaScript; this is the best approach to make use of your JWT while maintaining security best practices. For unattended processes, the client may also authenticate directly by generating and signing its own JWT with a pre-shared secret and passing it to an OAuth compliant service like so:
POST /oauth2/token
Content-type: application/x-www-form-urlencoded
grant_type=urn:ietf:params:oauth:grant-type:jwt-bearer&assertion=eyJhb...
When the client wants to access a protected route or resource, the user agent should send the JWT, typically in the
Authorization HTTP header using the Bearer schema. The content of the header might look like the following:Authorization: Bearer eyJhbGci...<snip>...yu5CSpyHI
This is a stateless authentication mechanism as the user state is never saved in server memory. The server's protected routes will check for a valid JWT in the Authorization header, and if it is present, the user will be allowed to access protected resources. As JWTs are self-contained, all the necessary information is there, reducing the need to query the database multiple times.
Standard fields
List of currently registered claim names can be obtained from IANA JSON Web Token Claims Registry.Implementations
JWT implementations exist for many languages and frameworks, including but not limited to:- .NET (C# VB.Net etc.)
- C
- C++
- Clojure
- Common Lisp
- Dart
- Elixir
- Erlang
- Go
- Haskell
- Java
- JavaScript
- Julia
- Lua
- Node.js
- OCaml
- Perl
- PHP
- PL/SQL
- PowerShell
- Python
- Racket
- Raku
- Ruby
- Rust
- Scala
- Swift
Vulnerabilities
JSON web tokens 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 that 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 JWTs.Security consultant Tim McLean reported vulnerabilities in some JWT libraries that used the
alg field to incorrectly validate tokens, most commonly by accepting a alg=none token. While these vulnerabilities were patched, McLean suggested deprecating the alg field altogether to prevent similar implementation confusion. Still, new alg=none vulnerabilities are still being found in the wild, with four CVEs filed in the 2018-2021 period having this cause.With proper design, developers can address algorithm vulnerabilities by taking precautions:
- Never let the JWT header alone drive verification
- Know the algorithms
- Use an appropriate key size
Some have argued that JSON web tokens are difficult to use securely due to the many different encryption algorithms and options available in the standard, and that alternate standards should be used instead for both web frontends and backends.