14

Considering that, by definition, a REST API is stateless: is the "logout" operation useless?

I mean, I'm creating a REST API using encrypted JWT. Each token has an expiration time of, let's say, 60 minutes. If I save on a database table the last tokens generated by the API, the "logout" would be done deleting them from the table of valid tokens. But, if I do that, I understand that the API will cease to be stateless, right?

So, I understand that I shouldn't do that. The only solution that I'm thinking is make the JWT expiration time shorter, to 5 minutes, don't implement a "logout" operation and just let the tokens expire.

Is this the correct approach?

Mario S
  • 1,914
  • 1
  • 19
  • 32

7 Answers7

10

I mean, I'm creating a REST API using encrypted JWT

The JSON Web Token (JWT) tokens encodes all the data about the grant into the token itself. The most important advantage of this approach is that you do not need a backend store for token storage at all. One disadvantage is that you can't easily revoke an access token, so they normally are granted with short expiry and the revocation is handled at the refresh token. Another disadvantage is that the tokens can get quite large if you are storing a lot of user credential information in them. So if:

If I save on a database table the last tokens generated by the API, the "logout" would be done deleting them from the table of valid tokens

Then you would lose the most important advantage of using JWT and also, still have all those disadvantages, which seems unreasonable to me.

So, I understand that I shouldn't do that. The only solution that I'm thinking is make the JWT expiration time shorter, to 5 minutes, don't implement a "logout" operation and just let the tokens expire.

Is this the correct approach?

In my opinion, if you're planning to use JWT, YES! it's better to rely on the token expiration. For more details on this approach you can check this question out.

Is “logout” useless on a REST API?

Regardless of the fact that you're using JWT and similar to any other decent questions on computer science, the answer would be It Depends. The most important advantage of Statelessness is that your API would be more scalable. If you choose this path, probably, every request on your API should be authenticated, since you may need to search a backend store for the given token or decode a JWT token. So, in this case you may have some performance cost on a single node but in a big picture, you would still have the scalability. I guess what i'm trying to say is, if you do not need that scalability, you're better off to choose a Stateful approach. Otherwise, pure REST principles is the way to go.

Community
  • 1
  • 1
Ali Dehghani
  • 46,221
  • 15
  • 164
  • 151
8

Automatic token expiry is a separate concern from an explicit "log out" mechanism and, as such, they are both perfectly valid actions regardless of whether your API is ReSTful or not.

When a user logs out they are making a conscious decision to invalidate their access token - for example, if they're using a public computer or borrowing someone else's device temporarily.

Automated expiry is used to ensure that the user must revalidate, in some fashion, on a regular basis. This is good for server-side security.

Access tokens are not about sharing session state between client and server - it's entirely possible to implement an access token system without shared state and the token itself doesn't implement session state, it's only used to verify that the user is who they claim to be. As such, access tokens are not really anything to do with the statefulness of the API.

sisyphus
  • 6,174
  • 1
  • 25
  • 35
2

I think it depends on the behavior that you want for your application, and how secure you need it to be. Do you really need to invalidate the token? For instance, you could just remove your token from your frontend (browser or app). In theory, it is the only place that stores that particular token. If the token is compromised, it will still be valid until it expires, though.

If you really need to invalidate it server side, a common approach would be to create a blacklist with the token, and clear the expired entries from time to time.

But what if you need your application to accept just one token for each user, like in a bank app that you can only be logged in one device at time? For that purpose the blacklist won't do the job, so you will need to store a single token for each user and check if the passed token is the same. At logout, you would just clear that unique entry. Or you may just use sessions.

So, it is not useless, It just depends on your application.

Edudjr
  • 1,676
  • 18
  • 28
1

I would argue that your API is already stateful just by the sheer fact that you have a token around. I also wouldn't get too hung up on REST purity, meaning that everything has to be stateless come hell or high water.

Put simply, if your application requires login, then you need a way to logout. You can't implement a short expiry because that's just going to be a really annoying experience to consumers of the API. And you can't just have no logout at all, because thats a potential security flaw.

I have a similar REST API that I support and I implemented a logout endpoint that is a DELETE call. It simply deletes the token information on the server side and clears any type of authentication for the logged in user.

TL;DR

No, a logout is not useless in a REST API. In fact, for APIs that require authentication, it is more or less a necessity.

sma
  • 9,449
  • 8
  • 51
  • 80
  • 1
    It appears that your implementation isn’t using JWT if you have to “delete token information and any other type of authentication for the logged in user...” – amucunguzi May 28 '20 at 16:57
1

With a short expiration time on the token I would think for most applications deleting the token from the client on logout would be a good solution. Anything more would rely on the server and no longer be stateless.

Tri Dave
  • 11
  • 1
  • 1
0

The good solution here would be to delete the token from the user. So typically when you log in, you will get back a token from the server and store it in localStorage or sessionStorage (depending on the user wanting to be logged in after closing the tab) in the browser, and then send the token from there in the headers with any request that you make to your api.

Then if the user logs out, you don't even contact the api (you don't make any requests to your server), you just clear the sessionStorage or localStorage, use the command localStorage.clear() or sessionStorage.clear() , and then if the user will want to send more requests, he'll have to login again in order to get another token.

One drawback to this approach is, that if a virus, for example gets the token from the local or session Storage before the user logs out then, it will still be able to send requests as you, as the token will still be valid. One solution to that would be to create a token blacklist in the database, and store the token there if the user logs out, until the token expiration time. However, every time the user would request something, the database would have to be consulted to check if his token is blacklisted, lengthening the process, and making your API stateful.

ms3300
  • 216
  • 6
  • 13
  • 1
    Putting access tokens in browser storage is terrible security for the reasons you mentioned - they should ideally be kept in an httpOnly cookie which cannot be programmatically accessed from the client side. – lawrence-witt Mar 16 '22 at 18:14
-1

You can generate a new token that it already expired i.e. expiration is 1sec. and pass it to the user. Any upcoming request will be invalid. This is not optimal solution though..

Adi
  • 1