JSON Web Token (JWT) is the most popular cross-domain authentication solution currently. I'll describe its principle and usage in this article.

1. Cross-domain Authentication

Internet services can't be separated from user authentication. The general process is as follows.

The user sends a username and password to the server. After the server has been verified, relevant data, such as user role, login time, and so on, will be saved in the current session. The server returns a session_id to the user, where is written in the user's Cookie. Each subsequent request by the user will pass the session_id back to the server via the Cookie. The server receives the session_id and finds the data saved before, thereby knowing the identity of the user.

The problem with the mode is that scaling is not good. Of course, there is no problem with a single machine. However, if it is a server cluster or a cross-domain service-oriented architecture, session data sharing is required so that each server can read the session.

For example, site A and site B offer the associated services of the same company. Now it's required that users only need to log in one of the websites, and then it will be automatically logged in another website. How to do it?

One solution is to persist the session data, writing to a database or another persistence layer. After receiving the request, various services request data from the persistence layer. The advantage of the solution is that the architecture is clear, while the disadvantage is that the engineering quantity is relatively large. In addition, if the persistence layer fails, it will fail at the single point.

Another solution is that the server simply doesn't save the session data, all the data is stored in the client, and each request is sent back to the server. JWT is a representative of this kind of solution.

2. Principle of JWT

The principle of JWT is that after server authentication, a JSON object will be generated and sent back to the user, as shown below.

{ "UserName": "Jam", "Role": "Admin", "Expire": "2018-08-03 20:15:56" }

Later, when the user communicates with the server, the JSON object will be sent back. The server solely relies on the object to identify the user. In order to prevent users from tampering with the data, the server will add a signature when generating the object (see below for details).

The server doesn't save any session data, that is, the server becomes stateless, making it easier to extend.

3. Data Structure of JWT

Actually, the JWT probably looks like this.

It's a very long string which is separated by the . into three parts. Note that there is no line breaks inside the JWT. The reason why it's written into a few lines here is just for the sake of display.

The three parts of the JWT are as follows.

Header

Payload

Signature

Write them into a line as follows.

Header.Payload.Signature

We'll introduce the three parts below.

3.1 Header

The Header part is a JSON object that describes the JWT's metadata, usually as follows.

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

In the above code, the alg property represents the algorithm of the signature, which is HMAC SHA256 (written as HS256) by default; the typ property represents the type of the token, and the JWT token is uniformly written as JWT.

Finally, convert the above JSON object into a string using the Base64URL algorithm (see below).

3.2 Payload

The Payload part is also a JSON object holding the data that needs to be passed. JWT specifies seven official fields for selection.

iss : issuer

exp : expiration time

sub : subject

aud : audience

nbf : Not Before

iat : Issued At

jti : JWT ID

In addition to the official fields, you can also define private fields in this part. Here is an example.

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

Note that JWT is unencrypted by default and can be read by anyone, so don't put secret information in this part.

The JSON object is also converted to a string using the Base64URL algorithm.

3.3 Signature

The Signature part is a signature to the first two parts to prevent data from being tampering with.

First, you need to specify a secret. The secret is only known to the server and cannot be disclosed to the user. Then, using the signature algorithm (it's HMAC SHA256 by default) specified in the Header to generate the signature according to the following formula.

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

After calculating out the signature, the three parts of Header, Payload, and Signature are combined into a string, and each part is separated by . , and then can be returned to the user.

3.4 Base64URL

As mentioned earlier, the algorithm for Header and Payload serialization is Base64URL . The algorithm is basically similar to the Base64 algorithm, but with some minor differences.

The JWT, acting as a token, may be placed in a URL (such as api.example.com/?token=xxx ). The three characters in Base64 are + , / and = , which have special meanings in the URL, so they should be replaced: = is omitted, + is replaced with - , / is replaced with _ . This is the Base64URL algorithm.

4. Usage of JWT

The client receives the JWT returned by the server, which can be stored in the Cookie or localStorage.

After that, the client will bring the JWT every time it communicates with the server. You can put it in the Cookie and send it automatically, but it won't cross the domain, so it's better to put it in the Header Authorization field requested by HTTP.

Authorization: Bearer <token>

Alternatively, when crossing-domain, the JWT is placed in the data body of the POST request.

5. Futures of JWT

(1) JWT is not encrypted by default, but it can be encrypted. Once the original Token is generated, it can be encrypted again with the secret.

(2) When JWT is not encrypted, secret data can't be written to JWT.

(3) JWT can be used not only for authentication, but also for exchanging information. Making effective use of JWT will reduce the number of the times the server queries the database.

(4) The biggest disadvantage of JWT is that because the server doesn't save the session state, it's impossible to abolish a token or change the token's permissions during use. That is, once the JWT is signed, it will remain in effect until it expires, unless the server has deployed additional logic.

(5) JWT itself contains the authentication information, so once the information is leaked, anyone can get all the permissions to the token. In order to reduce misappropriation, the validity period of the JWT should be set to be relatively short. And for some important permissions, the user should be authenticated again when using it.

(6) In order to reduce misappropriation, JWT should not use the HTTP protocol to transmit the code, but use the HTTPS protocol to transmit.

6. Reference