In-depth explanation of JWT (JSON Web Token)

1. Introduction to JWT

JSON Web Token (JWT) is an open standard (RFC 7519) that defines a compact and self-contained way to securely transmit information as JSON objects between parties. This information can be verified and trusted through digital signatures. The JWT can be signed with a secret (using the HMAC algorithm) or with a public/private key pair using RSA.

image

While JWTs can be encrypted to provide confidentiality between parties, we will focus on signed tokens. Signed tokens can verify the integrity of the claims contained within them, while encrypted tokens hide claims from other parties. When a token is signed with a public/private key pair, the signature also proves that only the party holding the private key is the signing party.

Let's explain some concepts further:

  • Compact :
    Due to their small size, JWTs can be sent via URLs, POST parameters or within HTTP headers. Plus, smaller size means faster transfer speeds.
  • Self-contained :
    The payload (Playload) contains all required information about the user, avoiding multiple queries to the database.

2. JWT applicable scenarios

  • Authentication :
    This is the most common case of using JWT. Once the user is logged in, each subsequent request will contain the JWT, allowing the user to access the routes, services and resources allowed by that token. Single sign-on is a feature that is widely used today with JWT because it has little overhead and can easily be used across different domains.
  • Information Exchange :
    JSON Web Tokens are a great way to securely transfer information between parties. Because JWTs can be signed: e.g. using a public/private key pair, it is certain that the sender is who they claim to be. Additionally, since the signature is calculated using the header and payload, you can also verify that the content has not been tampered with.

3. JWT structure

In compact form, a JWT consists of three parts separated by dots (.), which are:

  • Header
  • Payload
  • Signature

The JWT structure usually looks like this:

xxxxx.yyyyy.zzzzz

Let's introduce these three parts separately:

Header usually consists of two parts: the type of token, that is JWT. and commonly used hashing algorithms like HMAC SHA256 or RSA.
E.g:

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

The JSON of the Header part is Base64Url encoded to form the first part of the JWT.

Payload

The content of the statement is placed here. It can be said that it is the place to store the communication information. There are 3 kinds of declarations (Claims) in the definition:

  • Registered claims :
    These are a set of pre-defined claims that are not mandatory but recommended to provide a useful, interoperable set of claims. Some of them are: iss(issuer), exp(expiration time), sub(subject), aud(audience), etc. #Registered Claim Names#

  • Public claims :
    These can be freely defined by the person using the JWT. But to avoid conflicts, they should be defined in the IANA JSON Web Token Registry, or as a URI containing a collision-proof namespace.
  • Private claims :
    These are custom claims created in order to share information between parties who agree to use them but have neither registered nor public claims.

An example of Playload is as follows:

{
  "sub": "1234567890",
  "name": "John Doe",
  "admin": true
}

The JSON of the Playload part is Base64Url encoded to form the second part of the JWT.

Notice:

Note that for signed tokens, this information, albeit tamper-protected, is readable by anyone. Do not put secret information in the payload or header elements of the JWT unless encrypted. This is also the reason why many articles argue about the security of jwt, do not replace the server-side session state mechanism with JWT. Read this article for details: Stop Using Jwt For Sessions .

Signature

The third part of signature is used to verify the identity of the sender and is formed by the encryption of the first two parts.
To create the signed part, you must take the encoded header, encode the payload, the secret key, the algorithm specified in the header and sign it.
For example, if you wanted to use the HMAC SHA256 algorithm, the signature would be created as follows:

HMACSHA256(
  base64UrlEncode(header) + "." +
  base64UrlEncode(payload),
  secret)

3. JWT practice

The output of JWT is three dot-separated Base64-URL strings that can be passed easily in HTML and HTTP environments, while being more compact compared to XML-based standards such as SAML.

The following JWT example has the previous header and payload encoding and is signed with a secret key.

image

We can use the jwt.io debugger to decode, validate and generate JWTs:
image

4. How JWT works

In authentication, when the user successfully logs in with their credentials, a JSON Web Token will be returned and must be saved locally (usually in local storage, but cookies can also be used), instead of creating a session server and Return a cookie.

Regarding the way of storing the token (Token), security factors must be considered.
Reference: #Where to Store Tokens#

Whenever a user wants to access a protected route or resource, the user agent should send the JWT using the bearer scheme, usually a Authorizationfield in the request header, using the Bearerschema:

Authorization: Bearer <token>

This is a stateless authentication mechanism because user state is never kept in server memory. The server-protected route will check for a valid JWT in the Authorization header and, if present, allow the user to access the protected resource. Since the JWT is self-contained, all the necessary information is there, reducing the need to query the database multiple times.

This allows us to fully rely on stateless data APIs and even make requests to downstream services. It doesn't matter which domains are serving the API, so there won't be an issue with Cross-Origin Resource Sharing (CORS) since it doesn't use cookies.

image

Notice:

Note that with a signed token, all the information contained in the token is exposed to the user or other parties, even if they cannot change it. In JWT, no sensitive data, such as passwords, should be added to the Playload. If you put the user's password in the JWT, then a malicious third party can quickly know your password through Base64 decoding.

5. Frequently Asked Questions

① Is JWT safe?

The Base64 encoding method is reversible, that is, the content of the Token issued after encoding can be parsed. In general, we don't recommend putting sensitive information, such as a user's password, in the payload.

② Can the content of JWT Payload be forged?

One of the components of the JWT is the Signature, which prevents the content of the payload from being pushed back and modified by the Base64 reversible method. Because Signature is composed of Base64 through Header and Payload.

Yes, the loss of the cookie means that the identity can be forged. Therefore, the official recommended way to use it is to store it in LocalStorage and send it in the request header.

④ Space and length issues?

JWT Tokens are usually not too short in length, especially Stateless JWT Tokens. All data is compiled in the Token, which will soon exceed the size of the cookie (4K) or the URL length limit.

⑤ Token invalidation problem?

    1. After the Stateless JWT Token is issued, the token cannot be invalidated through the server side, and it must wait until the expiration time expires before it becomes invalid.
    1. Assuming that the Token is intercepted during this period, or the authorization scope is modified due to the difference in the authority management identity, it cannot prevent the issued Token from invalidating and require the user to request a new Token again.

6. JWT usage advice

  • Do not store sensitive information in Token.
  • Do not set the time limit in Payload to expbe too long.
  • Enable Only HttpXSS attack prevention.
  • If worried about replay attacks (replay attacks) can increase jti(JWT ID), exp(valid time) Claim.
  • Add a blacklist mechanism to the application layer of your application, and block it when necessary (this is a manual defense against the token being stolen by a third party).

[1] Stop using JWT for sessions:
http://cryto.net/~joepie91/blog/2016/06/13/stop-using-jwt-for-sessions/
[3] Use JWT The Right Way!:
https://stormpath.com/blog/jwt-the-right-way
[2] JSON Web Token 维基百科:
https://en.wikipedia.org/wiki/JSON_Web_Token

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325366769&siteId=291194637