"JWT", the authentication login scheme you must know

The full name of JWT is JSON Web Token, which is a very popular cross-domain authentication solution and is often used in single sign-on scenarios.

Some people think it is very easy to use. After using it, there is no need to use redis to implement the authentication process on the server side. However, some people think that it is inherently flawed and cannot be used at all.

Why is this?

Traditional authentication method

Speaking from a login scenario

You have used so many websites and apps, many of which require login, so let's choose a scene to talk about.

Take an e-commerce system as an example. If you want to place an order, you first need to register an account. After you have an account, you need to enter a user name (such as mobile phone number or email) and password to complete the login process. After you enter the system again within a period of time, you do not need to enter the user name and password. Only when you have not logged in for a long time (for example, you have not logged in for a month) to access the system, you need to enter the user name and password again.

For those websites or apps that are used frequently, it is usually not necessary to enter a password for a long time, so that after you change a computer or a mobile phone, you can’t remember the passwords of some frequently used websites or apps Up.

Early Cookie-Session authentication method

The early Internet was dominated by the web, and the client was a browser, so the Cookie-Session method was the most commonly used authentication method in the early days. Until now, some web sites still use this method for authentication.

The certification process is roughly as follows:

  1. The user enters the user name, password or uses the SMS verification code to log in to the system;
  2. After server authentication, create a Session message, save SessionID in cookie, and send it back to browser;
  3. The next time the client initiates a request, it will automatically bring the cookie information, and the server will obtain the Session information through the cookie for verification;

"JWT", the authentication login scheme you must know

 

But why is it a traditional authentication method, because now everyone has a smart phone, and many people do not use a computer. They usually use various apps on their phones, such as Taobao and Pinduoduo.
Under this trend, the traditional Cookie-Session has encountered some problems:
1. First of all, Cookie-Session can only be used in web scenarios. If it is an APP, there is no place for the APP to store cookies.
The current products basically provide both web and APP two ways of use, and some products even only have APP.

2. Take a step back and say that the product you make only supports the web, and cross-domain issues should also be considered, but cookies cannot cross domains.
Take Tmall Mall as an example. When you enter the Tmall Mall, you will see menus such as Tmall Supermarket, Tmall Global, and Tmall Members at the top. Clicking on these menus will enter different domains. The cookies under different domains are different. You can't get the cookies of domain B under domain A, even if it is a subdomain.

"JWT", the authentication login scheme you must know

 

3. If it is a distributed service, session synchronization needs to be considered.
Today's Internet websites and apps are basically distributed deployment, that is, there is more than one machine on the server side. When a user performs a login operation on the page, the login action must be a request to one of the servers. You have to save your identity information, the traditional way is to save Session.

Next, the question came. You have visited several pages. At this time, a request is load balanced and routed to another server (not the one you logged in). When the background receives the request, it needs to check the user's identity information and permissions, so the interface starts to obtain the user information from the Session. However, this server is not the one logged in at the time, and your Session is not saved, so the background service thinks that you are a non-logged user and cannot return data to you.

Therefore, in order to avoid this situation, it is necessary to do Session synchronization. After a server receives the login request, after the current server saves the session, it also needs to synchronize with several other servers.

4. Cookies have the risk of CSRF (cross-site request forgery). Cross-site request forgery is an attack method that coerces users to perform unintentional operations on currently logged-in Web applications. CSRF utilizes the trust of the website in the user's web browser. Simply put, the attacker uses some technical means to trick the user's browser to visit a website that he has authenticated and perform some operations (such as purchasing goods). Since the browser has been authenticated, the visited website will be considered as an operation initiated by a real user.
For example, I am a hacker and I found a CSRF vulnerability in a technical website that you frequently visit. Post articles support html format, and then I add some dangerous content in html, such as

 <img src="http://www.examplebank.com/withdraw?account=Alice&amount=1000&for=Badman">

Assuming that the address pointed to by src is the payment address of your usual shopping website (of course it is just an example, the real attack is not so simple), if you have logged in before and the cookie that identifies your identity information has been saved. When you scan the article I published, the CSRF attack will work as soon as the img tag is loaded, and you will pay this website without your knowledge.

Cookie-Session modified version

As there are many problems with traditional Cookie-Session authentication, the above scheme can be modified.
1. Modification of Cookie Since Cookie cannot be used in non-browser such as APP, then do not use cookie for client-side storage and use other methods instead.
What to change to?
Local storage can be used in the web, and the client database can be used in the APP, which can achieve cross-domain and avoid CSRF.

2. The server does not save the Session anymore. Take out the Session information and store it in a memory database such as Redis, which improves the speed and avoids Session synchronization problems;

After transformation, it becomes the following certification process:

  1. The user enters the user name, password or uses the SMS verification code to log in to the system;
  2. The server is verified, the data structure constructed by the authentication information is stored in Redis, and the key value is returned to the client;
  3. The client gets the returned key and stores it in local storage or local database;
  4. Next time the client requests again, append the key value to the header or request body;
  5. The server obtains authentication information from Redis according to the obtained key;

The following two pictures respectively demonstrate the process of first login and non-first login.

"JWT", the authentication login scheme you must know

 

"JWT", the authentication login scheme you must know

 

After a fierce transformation, the problems of the traditional Cookie-Session method have been solved. This transformation needs to be done by the developer in the project. Transformation is definitely time-consuming and laborious, and there may be loopholes.

JWT appearance

At this time, JWT is ready to play. JWT is a specific implementation of Cookie-Session modified version, which saves you the time to make wheels yourself. JWT has another advantage, that is, you do not need to store authentication information on the server ( For example, token), which is completely provided by the client. The server can verify the user's legitimacy according to the decryption algorithm provided by the JWT itself, and this process is safe.

If you are new to JWT, the most questionable point may be: Why can JWT completely rely on the client side (such as the browser side) to realize the authentication function, and all the authentication information exists on the client side. How to ensure security?

JWT data structure

The final form of JWT is a string, which consists of three parts: header , payload and signature , separated by " . ". Like the following:

"JWT", the authentication login scheme you must know

 

head

The header is expressed in JSON format and is used to indicate the token type and encryption algorithm. The format is as follows, which means that the JWT format is used, and the encryption algorithm is HS256. This is the most commonly used algorithm, and there are many others.

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

Corresponding to the red header part of the above figure, Base64 encoding is required.

Load

It is used to store the data required by the server, such as user information, such as name, gender, age, etc. It should be noted that important confidential information, such as passwords, should not be placed here.

{
  "name": "古时的风筝",
  "introduce": "英俊潇洒"
}

In addition, JWT also specifies 7 fields for developers to choose from.

  • iss (issuer): Issuer
  • exp (expiration time): expiration time
  • sub (subject): Subject
  • aud (audience): audience
  • nbf (Not Before): effective time
  • iat (Issued At): Issuing time
  • jti (JWT ID): number

This part of the information also needs to be Base64 encoded.

signature

The signature has a calculation formula.

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

Calculated using the HMACSHA256 algorithm, this method has two parameters. The first parameter is (base64-encoded header + base64-encoded payload) connected by dots, and the latter parameter is a custom string key. Expose to the client, but the server should know.

How to use

After understanding the structure and algorithm of JWT, how to use it? Suppose I have a website here.

1. When users log in to the website, they need to enter a user name, password or SMS verification to log in. When the login request reaches the server, the server verifies the account and password, and then calculates the JWT string and returns it to the client.

2. After the client gets the JWT string, it is stored in the cookie or the browser's LocalStorage.

3. Send the request again, such as when requesting the user to set the page, add the JWT string to the HTTP request header, or put it directly into the request body.

4. After the server gets this string of JWT strings, it uses the base64 header and base64 payload to calculate the signature part through the HMACSHA256 algorithm, and compares whether the calculation result is consistent with the transmitted signature part. If they are consistent, the request is indicated There is no problem. If they are inconsistent, the request has expired or is an illegal request.

"JWT", the authentication login scheme you must know

 

"JWT", the authentication login scheme you must know

 

How to ensure safety

The key to ensuring security is HMACSHA256 or the same type of encryption algorithm. Because the encryption process is irreversible, it cannot be decrypted to the key information according to the JWT transmitted to the front end.

In addition, the signatures obtained after encryption of different headers and payloads are different. Therefore, if someone changes the information in the payload part, the final encrypted result must be different from the one before the change, so the final verification The result is an illegal request.

Is it safe for others to get the full JWT?

Assuming that the payload part stores the fields related to the authority level, the robber wants to modify it to a higher authority level after getting the JWT string. As mentioned above, it will definitely not succeed in this case, because the encrypted signature will not be successful. Similarly, the server may be easily identified.

Then if the robber does not make changes and use it directly after getting it, there is no way. In order to prevent being stolen by the robber to a greater extent, the HTTPS protocol should be used instead of the HTTP protocol, which can effectively prevent some intermediate hijacking attacks. .

Some students are about to say, this is not safe, you can easily simulate the request after you get the JWT string. This is indeed the case, but the premise is how you can get it. Is there any other way besides the intermediate hijacking mentioned above?

Unless the robber takes your computer directly, in that case, I'm sorry, not only JWT is insecure, but any other websites and authentication methods are insecure.

"JWT", the authentication login scheme you must know

 

Although such cases are rare, you should still pay attention to setting the expiration time reasonably when using JWT, not too long.

one question

There is a problem with JWT that has caused many development teams to give up using it. Once a JWT token is issued, the server cannot discard it unless it expires. There are many applications that allow only the latest login client to be used normally by default, and multi-terminal login is not allowed. JWT cannot do it because a new token is issued, but the old token is still available before it expires. In this case, the server needs to add corresponding logic.

Commonly used JWT libraries

The JWT official website lists the libraries corresponding to various languages, among which the following are the Java ones.

"JWT", the authentication login scheme you must know

 

Take java-jwt as an example.

1. Import the corresponding Maven package.

<dependency>
    <groupId>com.auth0</groupId>
    <artifactId>java-jwt</artifactId>
    <version>3.10.3</version>
</dependency>

2. When logging in, call the create method to get a token and return it to the front end.

public static String create(){
  try {
    Algorithm algorithm = Algorithm.HMAC256("secret");
    String token = JWT.create()      .withIssuer("auth0")
      .withSubject("subject")
      .withClaim("name","古时的风筝")
      .withClaim("introduce","英俊潇洒")
      .sign(algorithm);    System.out.println(token);
    return token;
  } catch (JWTCreationException exception){
    //Invalid Signing configuration / Couldn't convert Claims.
    throw exception;
  }
}

3. After successful login, put the token in the header or request body when the request is initiated again, and the server verifies the token.

public static Boolean verify(String token){
  try {
    Algorithm algorithm = Algorithm.HMAC256("secret");
    JWTVerifier verifier = JWT.require(algorithm)
      .withIssuer("auth0")
      .build(); //Reusable verifier instance
    DecodedJWT jwt = verifier.verify(token);    String payload = jwt.getPayload();    String name = jwt.getClaim("name").asString();
    String introduce = jwt.getClaim("introduce").asString();
    System.out.println(payload);    System.out.println(name);    System.out.println(introduce);    return true;
  } catch (JWTVerificationException exception){
    //Invalid signature/claims
    return false;
  }}

4. Use the create method to generate the token and verify it with the verify method.

public static void main(String[] args){
  String token = create();
  Boolean result = verify(token);
  System.out.println(result);}

Get the following result

eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJzdWJqZWN0IiwiaW50cm9kdWNlIjoi6Iux5L-K5r2H5rSSIiwiaXNzIjoiYXV0aDAiLCJuYW1lIjoi5Y-k5pe255qE6aOO562dIn0.ooQ1K_XyljjHf34Nv5iJvg1MQgVe6jlphxv4eeFt8pA
eyJzdWIiOiJzdWJqZWN0IiwiaW50cm9kdWNlIjoi6Iux5L-K5r2H5rSSIiwiaXNzIjoiYXV0aDAiLCJuYW1lIjoi5Y-k5pe255qE6aOO562dIn0
古时的风筝英俊潇洒true

The JWT string created using the create method can be verified.

And if I modify the payload part of the JWT string and the part between the two dots, and then call the verify method to verify, a JWTVerificationException will occur and the verification cannot be passed.

Guess you like

Origin blog.csdn.net/GYHYCX/article/details/108779217