-
Notifications
You must be signed in to change notification settings - Fork 673
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Logout Functionality #28
Comments
Currently, there is no way to logout. I had planned to add a revocation view for tokens but I just don't have the time to do it right now. |
If refresh token were saved on database we can add a validation against it and perhaps invalidate compromised tokens. |
In my case I instantiated a One solution might be to edit the access token and add some kind of flag in the jwt encoding highlighting whether the token has been deactivated by logging out. I am not sure if this is the most effective way. |
Actually, that's probably the best way to do it as long as you're flushing the blacklist fairly frequently. If a token is expired, it will be flushed from the blacklist. There's really no other way to log someone out with JWT's other than to have a blacklist or to change the signing keys (logging everyone out). |
jpadilla/django-rest-framework-jwt#385 mentions the possibility of having different signing keys per user which allows to logout only the intended user, would there be a simple way to implement this? |
Hmm...yeah, I suppose that is another way. I can't think of a really straight forward way to do it right now. A possible drawback to that approach is that it could be difficult to coordinate using the same signing key across multiple services. |
You could add a judge that a token before the logout is invalid. If add tokens into db, why not to use sessions. |
Hi! I wrote a logout function, and I added a successful token refresh to the blacklist. But then I realized that when I send requests with access token in HTTP Header, I still get the value of success (code 200) without the unauthorized error (code 401) as expected. |
Would someone mind posting a gist of this working? Seems like something beneficial to the docs. |
@derek-adair I have created gist with logout view . |
Is it possible to change expires_at in current access token on logout request? |
Yes, but there are still unexpired access tokens with valid signatures out in the wild at that point. So doing that wouldn't really log anyone out. |
The way things are supposed to work is that you have some other communication channel to JWT-using services, such as a publish-subscribe setup, that would broadcast revoked tokens. Those other services would need to add them to their blacklists. This channel, IMHO, is outside the scope of this project, because we have no idea what it is (dbus, zeromq, smtp, who knows). The module user would be expected to add this support themselves, using the blacklist module (or equivalent) to track blacklisted tokens. |
@greyhare Yeah that seems correct. Although maybe we could add something like a signal that people could hook into if they want to build their own blacklisting channels. |
Right now, I guess the signal could be "blacklist object created" |
maybe it's better to use cache or redis for blacklist storage backend? Cache may be expired for instance in 24h. So this allows not to use cron tasks |
I haven't used Redis much myself. Can you tell it when to expire an object? If so, then you can just set object expiration time to token expiration time. Also, can you search for an object via its SHA-256 hash? The blacklists I've seen elsewhere just store the SHA-256 hashes of expired tokens, not the tokens themselves. |
The problem with Redis is that it's an in-memory database and therefore when it restarts it would log everyone back in (unless you use a Redis cluster or something). |
Could you guys please explain to me why do you store In the beginning, I was thinking about the saved database call on token validation, but if we are validating against blacklisted tokens, it will be the same, even worse. If you store only VALID tokens, then it is easy to revoke and you almost no need to clean anything, except of expired In our setup we did use REDIS to store valid tokens for users as DB call is quite expensive to do on every request (as we are validating tokens against misuse and we rotate refresh token every now and then). But a lot of people just do not have REDIS setup ready and depending on the users count, you can have OOM of REDIS unexpectedly if you are not running managed service on AWS for instance. |
@sshishov I like that idea of whitelist. There are definitely pros and cons to each, and I think the time consumption on whitelisting is much less than a full scan for the blacklist table. (even with a bunch of bots spamming, it wouldn't make a difference). HOWEVER, I think the biggest problem with whitelisting is the data storage requirement. If we're only blacklisting a certain few tokens, data is limited. If we accept majority of users, then you've got a huge database table that needs a cron job clearing that table for expired. Whitelisting with Redis is the same story. You don't want to fill up the data store too quickly if you're accepting the majority of incoming requests. |
Hello @Andrew-Chen-Wang . If you are using database, then every access of protected API will do DB call which is not desired when we are using JWT tokens (as it is self contained). Using REDIS, it is completely different story:
It is just my assumptions and possible ways to solve the problem without degradation of the performance. Update:Points to consider:
|
The reason you want a blacklist instead of a whitelist is because it's a much shorter list, and tokens can be removed from the blacklist when they expire. So authentication is just "is the JWT itself valid, and not in the blacklist?" Which is a hash operation plus a lookup on a small tree. Which gets back to one of the main reasons to use JWT is that you don't need to maintain a database of valid tokens shared among the hosts trying to authenticate the token. If you're okay with keeping a database of active tokens to authenticate against, you may as well be using the non-JWT random session token model. Some things regarding refresh tokens:
|
How can i invalidate the token after the user logout form the application before token expire? Clearing the token form client side is not enough for prevent the access to protected resources. Is there any other options or work round for invalidate the key?
The text was updated successfully, but these errors were encountered: