Do you really understand JWT?

It’s not long since I first started using JWT, and I found some of its self-contained features, which are very different from the Session mechanism. It is quite interesting, but if you get in touch with it, you will find many of its drawbacks. Here is an article by a big guy, written sincerely. Not bad.

Meet JWT

Shaped like

  • Such A.B.Ca string is what we call the JWT.
eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJxaWFubWlJZCI6InFtMTAzNTNzaEQiLCJpc3MiOiJhcHBfcW0xMDM1M3NoRCIsInBsYXRmb3JtIjoiYXBwIn0.cMNwyDTFVYMLL4e7ts50GFHTvlSJLDpePtHXzu7z9j4
  • JWT constitute about, you can check here .
  • 编码,签名,加密. In JWT, these three concepts are involved at the same time, and these basic knowledge are briefly introduced.

Encoding and decoding

  • Generally, encoding and decoding are for the convenience of expressing data in bytes 便于存储和网络传输. The entire JWT string will be placed in the HTTP Header or URL. In order to avoid accidents such as garbled parsing errors, encoding is necessary. In JWT to .three divided parts have been base64 encoded (whether the Secret Part base64 encoding is optional, header and payload are necessary base64 encoding). Note that one characteristic of encoding: the entire process of encoding and decoding is reversible. After knowing the encoding method, the entire JWT string is plaintext, and you can decode and view the content at any decoding website.
  • So pay attention to payload 是一定不能够携带敏感数据如密码等信息的that .

Signature

  • 签名的目的主要是为了验证我是“我”. The commonly used signature algorithm in JWT is HS256. Most people may not be familiar with this signature algorithm, but signature algorithms like md5 and sha are definitely well-known. The common feature of signature algorithms is that the entire process is irreversible. Since the main content (header, payload) before signing will be carried in the JWT string, it is necessary to use a signature algorithm with a key 密钥是服务器和签发者共享的. If the header part and the payload part are tampered with, since the tamperer does not know what the key is and cannot generate a new signature part, the server will not be able to pass. In JWT, the message body is transparent 使用签名可以保证消息不被篡改.

Encryption

  • 加密是将明文信息改变为难以读取的密文内容To make it unreadable. Only the object with the decryption method can restore the ciphertext to normal readable content through the decryption process. Encryption algorithms are usually divided into symmetric encryption (such as AES) and asymmetric encryption (such as RSA) according to different encryption methods. You may be wondering: "Where is the encryption algorithm involved in JWT?" In fact, the alg parameter in the first part (header) of JWT can specify different algorithms to generate the third part (signature). Most of the frameworks that support JWT at least All built-in rsa asymmetric encryption method. Here is the first question:

When it comes to rsa, most people think of asymmetric encryption algorithm first, and the third part of JWT clearly defines signature in English. Isn’t this a contradiction?

  • rsa 加密和 rsa 签名 These two concepts are easy to understand:
    • Since it is encryption, 自然是不希望别人知道我的消息(the point is not to be understood by people ), only I can decrypt it, so the public key is responsible for encryption, and the private key is responsible for decryption. This is most of the usage scenarios, using rsa to encrypt.
    • Since it is a signature, 自然是希望别人不能冒充我发消息(the point is not to be tampered with ), only I can issue the signature, so the private key is responsible for signing, and the public key is responsible for verification.
  • Therefore, when the client uses the rsa algorithm to generate the JWT string, it is "encrypted" with the private key, and the public key is public 谁都可以解密,内容也无法变更(the tamper cannot know the private key).
  • Therefore, there is no pure encryption process in JWT, but 使加密之虚,行签名之实.

What scenarios should be suitable to use JWT?

  • Let’s talk about a few scenarios. Note that not all of the following scenarios fit JWT.

One-time verification

  • For example, users need to send an email after registration allowed to activate the account, the message usually need to have a link, this link needs to have the following characteristics: 能够标识用户,该链接具有时效性(通常只允许几小时之内激活),不能被篡改以激活其他可能的账户. This scenario is very close to the characteristics of JWT. The fixed parameters in the JWT payload: iss issuer and exp expiration time are just for it.

Stateless authentication of restful api

  • 使用 JWT 来做 restful api 的身份认证It is also a use scheme worthy of praise. The client and the server share the secret; the expiration time is verified by the server, and the client is refreshed regularly; the signature information cannot be modified... spring security oauth jwt provides a complete JWT authentication system.

Use JWT to do single sign-on + session management (not recommended)

  • If you are considering using jwt+cookiein place session+cookie, strongly recommend you do not.
  • First of all, make it clear: using JWT to design a single sign-on system is a less rigorous statement. First, the premise of the cookie+jwt solution is non-cross-domain single sign-on (cookies cannot be automatically carried to other domain names). Secondly, the single sign-on system contains a lot of technical details, including at least identity authentication and session management, which does not involve authority management. If you think it is more abstract, you might as well use the traditional session+cookie single sign-on solution as an analogy. Usually we can choose spring security and spring session (session sharing) to build, and the 选择用 jwt 设计单点登录系统需要解决很多传统方案中同样存在和本不存在的问题following are listed in detail.

What should I do if the JWT token is leaked?

  • Many people at work will raise this question. In fact, in the traditional session+cookie scheme, if the sessionId is leaked, others can also steal your identity. Let's go back to the root cause, what scenarios will cause your JWT to be leaked.
  • Follow the following practices to protect your JWT from being leaked as much as possible:, 使用 https 加密你的应用when returning the JWT to the client, set httpOnly=true and use cookies instead of LocalStorage to store the JWT. In this way 可以防止 XSS 攻击和 CSRF 攻击(children’s shoes interested in these two attacks can look at spring Introduction to them in security (CSRF, XSS).

Logout and change password

  • In the traditional session+cookie scheme, the user clicks to log out 服务端清空 session 即可, because the state is saved on the server. But the jwt scheme is more difficult JWT 是无状态的to handle , because the server verifies the validity through calculations. It is not stored, so even if the client deletes the jwt, the jwt is still within the validity period, but in a free state. Analyze the pain points: The reason why the logout becomes complicated is the statelessness of JWT. Here are a few options, depending on the specific business to decide whether it is acceptable.
    • Just clear the client's cookie , so that the user will not carry the JWT when visiting, and the server will think that the user needs to log in again. This is a 典型的假注销behavior that the user shows to exit, in fact, at this time, the system can still be accessed with the corresponding JWT.
    • Clear or modify the secret corresponding to the user on the server side , so that after the user logs out, the JWT itself does not change, but because the secret does not exist or changes, the verification cannot be completed. This is 将 secret 设计成和用户相关the reason why.
    • With the help of third-party storage to manage the state of jwt , you can use JWT as the key to verify the existence of cache middleware such as redis. The scheme design is not difficult, but after the introduction of redis, it is 把无状态的 JWT 硬生生变成了有状态done, contrary to the original intention of JWT. In fact, this solution and session are almost the same.
  • Change Password is slightly different, assuming that number is up, change the password (user password is not JWT's secret) after 盗号者在原 JWT 有效期之内依旧可以继续访问系统, so just empty the cookie nature is not enough, then, 需要强制性的修改 secret. This can be handled in practice.

Renewal issues

  • The issue of renewal can be said to be the biggest reason for resisting the use of JWT instead of traditional session, because the design of JWT did not find that it considers renewal as a feature of itself. Traditional cookie renewal schemes are generally built in the framework. The session validity period is 30 minutes. If there is a visit within 30 minutes, the session validity period is refreshed to 30 minutes. And there is an exp expiration time parameter in the payload of JWT itself, to represent the timeliness of a JWT, and JWT wants to extend this exp is a bit involuntary, because the payload is involved in signing, once the expiration time is modified, the entire JWT The string changed JWT 的特性天然不支持续签,!
  • If you must use JWT for session management (session information is stored in the payload), it is not without a solution, but I personally think that it is not very satisfactory.

Refresh JWT on every request

  • After the JWT modifies the exp in the payload, the entire JWT string will change, so... let it be better, and each request will return a new JWT to the client. Too violent, no need to go into details 多么的不优雅,以及带来的性能问题.

Just refresh jwt when it is about to expire

  • The transformation point of one of the above schemes is to return a new JWT to the client only in the last few minutes. In this way, triggering the refresh of the JWT basically depends on luck. If the user happens to access the server in the last few minutes and the refresh is triggered, everything will be fine; if the user operates continuously for 27 minutes, only the last 3 minutes of no operation will cause the JWT not to be refreshed. , Will undoubtedly make users crazy.

Perfect refreshToken

  • Learn from the design of oauth2 and return a refreshToken to the client to allow the client to actively refresh the JWT. Generally speaking, the expiration time of JWT can be set to several hours, and the expiration time of refreshToken is set to several days.

Use redis to record independent expiration time

  • In order to solve the renewal problem, you can set the expiration time for each JWT separately in redis, and refresh the expiration time of the JWT every time you visit. If the JWT does not exist in redis, it will be considered expired. The process of JWT is also changed, but well, there is peace of mind in the world. I can only advise friends who have not yet used JWT for session management, try to choose the traditional session+cookie solution. There are many mature distributed session frameworks and security frameworks for you to use out of the box.

to sum up

  • In web applications, using JWT instead of session is not a small risk. You must at least solve the problems mentioned in this article. In most cases, the traditional cookie-session mechanism works better. JWT is suitable for simple restful api authentication. A JWT with a fixed validity period is issued to reduce the risk of JWT exposure. Do not perform server-side state management on JWT, so as to reflect the stateless advantage of jwt.

Guess you like

Origin blog.csdn.net/qq_36221788/article/details/106950578