4

I own a stateless architecture, exchanging a JWT token between client and server at authentication time.

I want to store in database (once per day) a timestamp related to the user access.
Indeed, I would like to be able to show who was accessing the app, with a margin of 1 day (kind of rather online users).

A good solution (to avoid hitting database at each client request) I guessed would be to add a property to the JWT token called recentUserAccessTimestamp and to send it to the client at every request.

Question is: Is it a good practice to make the client replace its existing token (in LocalStorage for instance in case of WebApp) right after each request on my server?

16
  • Would this not then make it stateful?
    – Matthew
    Dec 28, 2015 at 19:01
  • Stateless in a sense that there is nothing stored in memory (no Memcache, no Redis etc..).
    – Mik378
    Dec 28, 2015 at 19:05
  • That is different than what most people would consider a stateless service. Stateless typically implies that no state information is passed between client and server. If the server wants to cache things, then that would be opaque to the client.
    – Matthew
    Dec 28, 2015 at 19:07
  • 2
    I think the exact contrary : stateless promotes exchanging information between client and server without storing anything on the server. What I want to store in database is not a direct result of one of those exchanges. The server does not store information of connection or anything else relative to a particular client instance.
    – Mik378
    Dec 28, 2015 at 19:11
  • I think we may have the same view, just worded differently. In either case, I think it would be worth while to simply store this information server side in the database in some sort of logging / audit table. Just because your application may be saving this information doesn't mean the exposed service has to behave differently because of it.
    – Matthew
    Dec 28, 2015 at 19:16

2 Answers 2

1

You can certainly rotate the JWT across requests, but you'll quickly run into a couple problems:

  • What side-channel do you use to issue the JWT? A HTTP response header? An augmented response body?
  • How can a client issue more than one concurrent request? The JWT is rotated across request/response cycles, so reusing an existing JWT will result in funky race conditions.

You said that you don't want to update the DB on every client request. But if you rotate the JWT, would you not have to store the new JWT in Redis or another persistence mechanism anyway? Therefore I think that you should simply store the user access data upon each request.

Marketing folks go bananas for the kind of analytics data you'll be capturing. By storing it en masse, you might just save a coworker a lot of pain down the line, and it will make you look like a hero.

One final thought. If you can tolerate some loss of the data in question, just write it to an in-memory queue in your main application. A background thread can periodically flush the data to a persistence store. Now everyone wins.

1
  • this part is wrong : "would you not have to store the new JWT in Redis" => JWT token is only stored on client ( localstorage in my case) , never on server, that s the whole benefit of JWT.
    – Mik378
    Dec 29, 2015 at 7:53
0

I was looking for this a few minutes earlier and I stumbled upon this question. It's weird, I was expecting to get straight to the point answers to this.

So I came up with mine. I believe the best way to do it is to handle it through a 3rd party or even a second server of yours. i.e.: if you're building a mobile app, you could integrate an analytics tool that allows you to set sessions both on successful logins and logouts.

If you don't have control over the clients and want to do it server side:

  • Set the expiration time of your tokens to something low - about 1 or 2 hours.
  • Create a good token refreshing mechanism for the clients
  • Add a new latest_activity - or whatever you want - date time column/field to your user - or whatever you call it - table/collection
  • On every successful request from a client - user is authorized, update this column for the user's row and set it to current date and time - create a utility function for this.
  • When analysing, you can safely assume that if you haven't received any request from a user within 1/2 hours - hence the short lifetime for your token above, the user is logged out.

You could even do this in a different database altogether, something like SQLite. Much faster.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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