Background:

Differences between Authentication and Authorization:

Authentication: User Authentication refers to the Authentication of the user. For example, if you want to log in as A user, the application needs to verify that you are really A user through the user name and password.

Authorization refers to granting you Authorization after confirming your identity. For example, user A can modify data, while user B can only read data.

Since the HTTP protocol is stateless, each request is stateless. When a user logs in with a username and password, his next request carries no status, and the application has no way of knowing his identity and must be re-authenticated. So we want the user’s login status to be saved for every HTTP request after a successful login.

At present, the mainstream user authentication methods are token-based and session-based.

Session-based user authentication

The session-based authentication process is as follows:

  1. The user enters his login information

  2. The server verifies that the information is correct, creates a session, and stores it in the database

  3. The server generates a sessionId for the user and places cookies with sesssionId in the user’s browser

  4. On subsequent requests, the sessionID is validated against the database and, if valid, the request is accepted

  5. Once the user logs out of the application, the session is destroyed on both the client and server side

Token-based user authentication

The most commonly used is JSON Web Token (JWT) :

  1. The user enters his login information

  2. The server verifies that the information is correct and returns the signed token

  3. The token is stored on the client, for example, in a local storage or cookie

  4. Subsequent HTTP requests add the token to the request header

  5. The server decodes the JWT and, if the token is valid, accepts the request

  6. Once the user logs out, the token is destroyed on the client side and no interaction with the server is required. One key point is that the token is stateless. The back-end server does not need to save tokens or records of the current session.

The composition of JWT

JWT certification principle:

A JWT is essentially a string made up of three parts, the header, payload, and signature, all in JSON format.

Header

The header describes the most basic information about the JWT, such as its type and the algorithm used to sign it.

{
  "typ": "JWT"."alg": "HS256"
}
Copy the code

Here, we show that this is a JWT and that the signature algorithm we use is the HS256 algorithm.

Payload

The payload can be used to store insensitive information.

{
    "iss": "John Wu JWT"."iat": 1441593502,
    "exp": 1441594722,
    "aud": "www.example.com"."sub": "[email protected]"."from_user": "B"."target_user": "A"
}
Copy the code

The first five fields are defined by JWT standards.

  • Iss: The issuer of the JWT
  • Sub: The user for which the JWT is intended
  • Aud: The party receiving the JWT
  • Exp (Expires): When does it expire, in this case a Unix timestamp
  • Iat (issued at): when issued Two strings are derived from Base64 encoding of the header and payload respectively, and then the two encoded strings are issued with an English period. Concatenated (head first) to form a new string:
eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJmcm9tX3VzZXIiOiJCIiwidGFyZ2V0X3VzZXIiOiJBIn0
Copy the code

Signature

Finally, we use HS256 algorithm to encrypt the above concatenated string. When encrypting, we also need to provide a secret. The encrypted content is also a string, and the last string is the signature. Concatenate the signature after the previous string to get the complete JWT. If the header and payload parts are tampered with, the tamper does not know what the key is and cannot generate a new signature part, so the server cannot pass. In JWT, the message body is transparent and the signature is used to ensure that the message is not tampered with.

eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJmcm9tX3VzZXIiOiJCIiwidGFyZ2V0X3VzZXIiOiJBIn0.rSWamyAYwuHCo7IFAgd1oRpSP7nzL7BF5t7 ItqpKViMCopy the code

Differences and advantages:

The main difference between session-based and JWT-BASED approaches is where the user’s state is stored. The Session is stored on the server, while the JWT is stored on the client.

Advantages of JWT:

  1. Good scalability In the case of distributed application deployment, session data needs to be shared among multiple machines, which can be stored in databases or Redis. JWT does not.

  2. Stateless JWT does not store any state on the server. One of the tenets of RESTful apis is stateless: when a request is made, it always returns a response with parameters, with no additional impact. The user’s authentication status undermines this principle by introducing this additional effect. In addition, some common information can be stored in the payload of JWT for information exchange. Using JWT effectively can reduce The Times of database query by the server.

Disadvantages of JWT:

  1. security

The JWT payload is base64 encoded and not encrypted. Therefore, sensitive data cannot be stored in the JWT. Session information is stored on the server side, which is more secure.

  1. performance

JWT is too long. Due to stateless use of JWT, all data are put into JWT. If some data exchange is needed, the load will be larger and the JWT will be very long after encoding. The limit size of cookies is generally 4K, so cookies may not fit, so JWT is generally stored in local storage. And every HTTP request the user makes in the system carries the JWT inside the Header, which may be larger than the Body. The sessionId is a very short string, so HTTP requests using JWT are much more expensive than sessions.

  1. A one-time

Statelessness is a feature of JWT, but it also causes this problem. JWT is disposable. To modify the contents, you must issue a new JWT.

It can be seen from the verification mechanism of JWT above that once a JWT is issued, it will always be valid before it expires and cannot be abandoned midway. For example, you store some information in the payload. When the information needs to be updated, a new JWT is issued. However, you can log in with the old JWT. To solve this problem, we need to deploy additional logic on the server side, such as setting up a blacklist. Once a new JWT is issued, the old one is added to the blacklist (e.g. stored in Redis) to avoid being used again.

If you use JWT for session management, the traditional cookie renewal scheme is generally built in the framework. The session validity period is 30 minutes. If there is access within 30 minutes, the validity period will be updated to 30 minutes. In the same way, to change the duration of a JWT, a new JWT is issued. The simplest way to do this is to refresh the JWT per request, which means that each HTTP request returns a new JWT. This method is not only violent and inelegant, but also requires JWT encryption and decryption on every request, causing performance problems. Another approach is to set the expiration time for each JWT individually in Redis and refresh the EXPIRATION time for the JWT on each access.

As you can see, to crack the JWT one-off feature, you need to store the JWT state on the server. However, after the introduction of Redis, the stateless JWT becomes stateful, which violates the original intention of JWT. And this scheme is pretty much the same as session.

conclusion

Suitable scenarios for using JWT:

  • The validity of short
  • You only want to be used once

For example, when a user signs up to send an email asking them to activate their account, the email usually requires a link that identifies the user, is time-sensitive (usually only allowed to activate within a few hours), and cannot be tampered with to activate other possible accounts, once and for all. This scenario is suitable for JWT.

And because JWT is disposable. Single sign-on and session management are very unsuitable for JWT, and if you deploy additional logical storage of JWT state on the server, you might as well use sessions. There are a number of mature session-based frameworks that work out of the box, but you need to implement your own logic with JWT.