Some Thoughts on JWT
Json Web Token (abbreviated as JWT) is an authentication method. Unlike the traditional Session mode, JWT does not require the server to save the user's login status, i.e., stateless, but chooses to save the status in the Token using asymmetric encryption. Users can use this token to access various resources.
This stateless authentication method, with the popularity of microservices, is being used more and more. This allows various resource services in the backend to be decoupled from the authentication services. The resource server receives data that is a piece of user information that has been parsed by the gateway or middleware. It can perform corresponding operations based on this information.
Why should we use the combination of AccessToken+RefreshToken?¶
Using only AccessToken can naturally achieve authentication + refresh. The general approach is to include access_expire_timeout and refresh_expire_timeout in the AccessToken to indicate the operations that this token can perform. However, this method has security issues, just like a token being both an athlete and a referee, it can access resources and refresh. Once this token is leaked, it is difficult to limit this token.
By separating the permissions of accessing resources and refreshing tokens into AccessToken and RefreshToken respectively, we can isolate the permissions, which ensures security to a certain extent.
- If the AccessToken is leaked, due to its relatively short expiration time (a few tens of minutes), it will not have a significant impact.
- If the RefreshToken is leaked, it would be difficult for a third party to use it illegally, as device information is required when refreshing.
What information should AccessToken and RefreshToken contain?¶
Just like AccessToken, RefreshToken is also a JWT, but the expiration time and the amount of information contained are different.
The RefreshToken only needs to contain basic user ID + device ID, ensuring that the corresponding device can be located when refreshing.
Correspondingly, the RefreshToken can also only store this information, but in order to prevent unnecessary requests to other services, it can store more redundant information.
Should AccessToken and RefreshToken use different KeyPairs?¶
If your AccessToken and RefreshToken can be decrypted with the same set of keys, and coincidentally, both AccessToken and RefreshToken contain similar information, then users can completely use RefreshToken as AccessToken for access, without worrying about expiration. This can lead to significant security issues.
The solution is to use different keys for encryption and decryption, ensuring that the two tokens cannot replace each other.
How to blacklist a set of Tokens?¶
One of the purposes of using JWT is that it eliminates the need to store user tokens on the server side. Therefore, if you want to blacklist a user or a device, there's no way to know the corresponding token for this user or device. Of course, you can establish a global user blacklist and check it every time a resource is accessed, but this violates the design principle that the resource server does not need to operate user authentication.
Of course, it can also be handled from the perspective of RefreshToken. Since the refresh operation is not frequent, but due to the short expiration time of AccessToken, the refresh operation will be performed after a short period of time. If at the time of refresh, the decision whether to refresh can be made based on the user information and device information contained in it. In this way, it will not impose any burden on the resource server.
How to implement immediate forced logoff without delay?¶
As mentioned above, the longest delay for implementing a logout is the expiration time of the AccessToken. If it involves sensitive information and there is a need to immediately log out risky users or devices, it becomes quite difficult to achieve.
By refreshing during the cold start of the App or the opening of the webpage, the harm can be minimized as much as possible. However, it still cannot meet the requirements very well.
We often see a list of all devices in the security centers of Google, Telegram, and the like, where we can choose to log out a device immediately. Assuming that this product also uses OAuth, how is this implemented?
Assumed Operation Process:
- Put the corresponding device into a blacklist.
- If the device is online, it can be asked to refresh or directly log out through push notifications. (However, this is another topic.)
- If the device is offline, executing a refresh at the next startup can also achieve the offline effect.