6

I have a web API in .net core 1.0 which issues JWT token(access_token) to the clients at login. Now, the token has a short expiry period(10 mins) and the client requests a new token in every 8 mins for the continuity of the session. This token is stored in the cookie in the browser at the client side. Now, this works fine if the client works in only one tab of the browser. However, if the client opens two or more tabs, every 8 minutes request for a new token is made to the API. This results in multiple requests from the same user simultaneously and my application issues token for each and every request but only one of the tokens is stored at client side cookie. But it results in multiple token out of which only single one is used throughout its lifetime.

I have tried storing the userId and token in DB and cross-checking them during API request, however, the same user in multiple tabs makes simultaneous request and the logic fails here.

How can I resolve this situation? I want my API to issue only one token per user opened in multiple tabs. Any help is appreciated.

  • so you want your API to issue a single token for every user request even if they have multiple tabs open? – Sparsha Bhattarai Nov 14 '17 at 11:54
  • Yes, for the same user opened in multiple tabs. – saurabhadhikari Nov 14 '17 at 11:58
  • 3
    You need to share the token betweeb tabs. The front-end should reuse it when available or request a new one and provide it to the rest of tabs. It can be done using localStorage instead of cookie and events to communicate a change. See https://stackoverflow.com/questions/20325763/browser-sessionstorage-share-between-tabs – pedrofb Nov 14 '17 at 12:03
  • No, it's not about sharing the token between the tabs. Each opened tab can make independent request to the API and can get token on valid condition which will be satisfied by both the request as they are concurrent. – saurabhadhikari Nov 14 '17 at 13:15
  • With an assumption that there would be a certain delay between API requests of each tab, you can use localStorage like Pedro mentioned albeit in a different manner. You can have your JavaScript code store the local time in the localStorage and check with the previous stored time before every API call. So, if you have 2 tabs open at the same time, the first tab stores the local time in the localStorage before making the API request. The second tab, however, before making the request compares the localStorage date with local time and makes or doesn't make the call based on time difference. – Sparsha Bhattarai Nov 14 '17 at 17:21
  • Alternatively, you could separate the storage of each tab using sessionStorage instead of cookies. In this way each tab would have its token and avoid concurrency problems – pedrofb Nov 15 '17 at 07:12
  • You can set the localStorage with the time the token was requested. Then in the code, check if that time is greater than 8 minutes. If it is greater get the token and update the localStorage with the new time. – Prashant Mothukuri Nov 17 '17 at 19:34

1 Answers1

1

This is tricky. If you try to store the token in the DB and not issue a fresh token until the old expires it will create a plethora of problems. Think of the case, when the user uses multiple devices. This logic won't work. There are many more cases.

And storing the JWT in the server is very redundant and counter-intuitive, IMO. One of the primary benefits of JWT is that you don't have to make a DB call everytime a protected resource is requested. The JWT itself has all the information for authorizing the user.

I believe, the solution you are looking for is throttling or rate limiting. You can limit the token issue endpoint to 1request/sec/ip (experiment and find the rate which works well). The idea is to block the concurrent requests for new token issues from the same IP and process just one of them. You can achieve this through IIS or through Attributes. Play around and see what works best for you.

mrtyormaa
  • 862
  • 1
  • 7
  • 17