How to use jti claim in a JWT

后端 未结 3 1866
夕颜
夕颜 2021-01-29 23:08

The JWT spec mentions a jti claim which allegedly can be used as a nonce to prevent replay attacks:

The "jti" (JWT ID) claim provides a unique iden

3条回答
  •  别那么骄傲
    2021-01-30 00:01

    This is an old question, but I just worked on something similar. So I will share my thoughts here.

    First of all, I agree that making database calls while validating JWT tokens undermines their primary advantage of being stateless.

    None of the previous answers mention refresh tokens, but I believe they present a good trade-off between scalability and security.

    In short, one can use regular auth tokens with a short expiration time (say, 15 minutes) and refresh tokens with long-lived access (say, 2 weeks). Whenever an auth token expires, the refresh token (stored more securely) is used to generate a new auth token without the user having to log in again.

    The jti claim is best suited for refresh tokens. That gives you the ability to revoke access while minimizing the number of database calls made.

    Let's say an average user session is 30 minutes. If you have a jti claim on regular auth tokens, then every API call is doing at least one extra database call to check if the token is not blacklisted. However, if you're only using a jti claim on refresh tokens, you will only make 2 database calls for authentication purposes during the course of a 30 minutes session (assuming each auth token expires after 15 minutes). That's a big difference.

    Regarding implementation, you can use a randomly-generated UID and use it as your table's primary key. That guarantees the calls are as fast as possible. Moreover, you can add an expiration_time column with the same value as the exp claim. That way you can easily (batch) remove all the expired refresh tokens.

    Why use a JWT instead of just storing a randomly-generated session ID in a database?

    Or, if I may paraphrase, "why would you use a JWT refresh token rather than a random string saved on the database?"

    I think you can do that, but using a JWT token has at least two advantages: (1) if the token is invalid or expired (when you decode it), you don't have to make any database calls at all. You just return a response with an error status code. (2) if you have a big system, you might be storing the "random strings" in different database tables based on some criteria (say, per client application [web vs mobile]). How would you know the table in which to look up the random string? With a JWT token, you can simply add a client_id claim. So, the ability to have information in the token is useful.

提交回复
热议问题