Styria-Digital / django-rest-framework-jwt

JSON Web Token Authentication support for Django REST Framework
https://styria-digital.github.io/django-rest-framework-jwt/
MIT License
191 stars 57 forks source link

Paradox leading to non-usability: You can't refresh a token that's no longer there. Or am I misunderstanding this? #74

Open ronenmagid opened 4 years ago

ronenmagid commented 4 years ago

Using HttpOnly tokens for security. Let's say the token has 30 seconds of life with 90 minutes to renew -- using JWT_EXPIRATION_DELTA': timedelta(seconds=30) and JWT_REFRESH_EXPIRATION_DELTA': timedelta(minutes=90)

So I send my /token-auth request with a user and password. I receive a token back good for 30 seconds.

This is from the response header:

Set-Cookie: my-token=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VybmFtZSI6InJvbmVubWFnaWQrZmlsbXNpbnRsQGdtYWlsLmNvbSIsImlhdCI6MTU5ODQ3MzIyMiwiZXhwIjoxNTk4NDczMjUyLCJqdGkiOiI3YzEwZTJhMi0wZjQ0LTQ3NjAtOTg3MS0yMmNmNmM4MTI4ZTYiLCJ1c2VyX2lkIjoiNjEyODRjNDItYTdjOS00YWM1LWExZjYtMDY0YzNjOTI1OTVkIiwib3JpZ19pYXQiOjE1OTg0NzMyMjJ9.Y9DIw6ldGog-fsnMFph9ObmVQog1KWhTBjYxnM3u8N4; expires=Wed, 26 Aug 2020 20:20:52 GMT; HttpOnly; Max-Age=30; Path=/; SameSite=None; Secure

So I keep sending subsequent request during the 30 seconds, all is good. The request header reads:

Cookie: my-token=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VybmFtZSI6InJvbmVubWFnaWQrZmlsbXNpbnRsQGdtYWlsLmNvbSIsImlhdCI6MTU5ODQ3MzIyMiwiZXhwIjoxNTk4NDczMjUyLCJqdGkiOiI3YzEwZTJhMi0wZjQ0LTQ3NjAtOTg3MS0yMmNmNmM4MTI4ZTYiLCJ1c2VyX2lkIjoiNjEyODRjNDItYTdjOS00YWM1LWExZjYtMDY0YzNjOTI1OTVkIiwib3JpZ19pYXQiOjE1OTg0NzMyMjJ9.Y9DIw6ldGog-fsnMFph9ObmVQog1KWhTBjYxnM3u8N4

Now the 30 seconds expire.... the next request gets an understandable 401 but when I look at it's request header: The Token is gone, it's not used. It's been erased from Chrome.

Given that --- how can I use /token-refresh when it requires something I no longer have?

It's almost as if you are forced to renew it before it expires. But if this is the case, what's the point of having a longer JWT_REFRESH_EXPIRATION_DELTA?

fitodic commented 3 years ago

@ronenmagid Hi! Sorry for the late response.

It's almost as if you are forced to renew it before it expires. But if this is the case, what's the point of having a longer JWT_REFRESH_EXPIRATION_DELTA?

You're right, it is perplexing when the client relies solely on cookies for authentication. If I remember correctly, the expiration delta settings are useful when the clients have access to the JWT and are able to resend it after expiration to refresh it. For example, after acquiring the token, the client relies on the cookie until the cookie expires. Then it uses the JWT that it received in the response to refresh it, which defeats the purpose of the HttpOnly cookie from a security standpoint.

It's not ideal, but perhaps someone else knows of a better workaround.