1

I have an app that uses JWT tokens for user authorization. Now, I need to be capable of deactivating users (users won't be allowed to use the system but still exist in the database), but as a requirement for that, I need to know if the user is not logged in. Is there some kind of best practice for handling this kind of scenario?

Example: admin gets a list of users -> admin selects one user to deactivate -> the server checks if the user to be deactivated is not logged in -> if it is, don't deactivate and return an error to admin, else, deactivate and return success to admin.

The way I thought about doing this was using a smaller expiration time for the token (to be refreshed) and store the last one generated in the user's table so that I can check (with the expiration) if there has been a recent user activity.

Update: Every time a user logs in a new token is generated. There is a logout option, it blacklists the user's token so that it can't be used again.

  • 1
    This isn't really something that can be solved, until you dig into the justification for the odd requirement that a "logged in" user cannot be deactivated. When you figure out the motivation for that odd idea, you'll be able to figure out how to best approximate it - for example, you might accelerate the expiration of any session and prohibit new ones, or you might change the absolute block to a warning that the user has been recently active. The whole point of such authentication schemes is that you don't actually know if the user is ever going to come back with that token, or not. – Chris Stratton Mar 9 '19 at 14:10
  • 1
    It sounds like "deactivation" actually means "prevent future logins", which is kind of weird in my opinion. But if that's what you want, you can just set a flag saying that the next time the user tries to login, no token will be generated. Or am I missing something? – ChatterOne Mar 11 '19 at 10:58
0

There are several cases:

If your application doesn't have a logout button, then you might not have a well-defined concept of what it means to be logged in. In which case I'd seek clarification on whether the need can be met in terms of recent activity. If so, there's no reason to mess with expiration times, just update some table with last_activity_time = now when the user does something. (I'm saying "some table" because the question of whether it's better to add a column to the user table or to add a "recent activity" table is beyond the scope of this answer.)

If you do have a logout button, then it should be updating some table to indicate that the user isn't logged in so that subsequent requests from that user aren't accepted if accompanied by the token used to authenticate the logout request. (This assumes when they log in again they get a new token.) The token they have is still valid in the sense that your application really did issue it to them; I'm asserting that the presence of a logout button changes the app logic for "do I accept this request" to include the concept of "did they log out" rather than just "is the accompanying token valid."

If you have a logout button and all it does is wipe the client side token, then I'd argue the app is broken and would go back to the question of what it actually means to log out.

If a significant portion of the users close or abandon the browser window without logging out, then I'd push back on the "server checks if the user to be deactivated is not logged in" requirement. (In that case "logged in" might be well-defined but still not useful, so it's back to the "recent activity" idea.)

| improve this answer | |
0

The following comes with a (big) grain of salt, because my knowledge of JWT is only theoretical, but I am trying to give a helpful answer:

You have a login process in which the credentials are checked and - based on business rules - the user is or is not allowed to log in; perhaps he was banned etc. As a positive result this user is getting a token in return, which has an issuing date as well as an expiry date; in case of a negative result the user gets - of course - no new token. The token he got authenticates the user for as long as the expiry allows. So there might be a gap between the point in time, you do not want the user to use your service and the point in time when the valid token expires.

A viable solution would be to propagate the information that tokens for a given user before a given point in time are invalid. This information has to be stored at the according servive as long as the given token is itself isn't expired:

Say your tokens live for two hours, this information could be discarded after two hours. So you prevent littering your "bad tokens"-table.

If the user visits your site before the expiry, the token is thrown as immediately away as the information is propagated through your system. If he tries to log in, he doesn't get a fresh token; the same goes of course for the refresh option.


I need to know if the user is not logged in [...] admin gets a list of users -> admin selects one user to deactivate -> the server checks if the user to be deactivated is not logged in -> if it is, don't deactivate and return an error to admin, else, deactivate and return success to admin.

What is the background for that?

Update: Every time a user logs in a new token is generated. There is a logout option, it blacklists the user's token so that it can't be used again.

Is there a reason for "blacklisting" a token instead of rendering it useless with an expiry date in the past and throwing a token away?

What information do you store in your token, if any?

| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.