Reputation: 461
I'm making a rather straightforward angular app that requires a couple different levels of authentication and I came across JSON web tokens as a way to implement this.
I've read several places to make the lifetime of tokens really short to improve security but, what if the user is still logged in and actively accessing the site when their token expires?
I guess I could also add some sort of refresh token along with the access token, but would that be too much work than necessary?
I guess I'm just wondering how widely adopted JWT is and if using some stateful authentication method would be better for my app. How do other popular sites deal with this issue of token expiration?
Upvotes: 1
Views: 285
Reputation: 15599
JWTs are indeed very popular, but that doesn't mean they are the best tool for any job. First there were plain stateful websites that wanted to maintain user sessions. They used cookies to store a session id, and all was well. Then APIs became a thing, and the problem was that cookies are only sent to their origin. Javascript can read a cookie if it is not set as httpOnly, but if it is a sesaion id, it will still be of no use on a different api. So something stateless is needed, something that is valid by itself, and that's where a token like a JWT can help, as it is accessed by javacript and can be sent anywhere. However, the cost of this is some security - primarily, cross-site scripting (xss) can be used to steal a token, while it is not possible with an httpOnly cookie.
If your client application (javascript) only talks to its own origin (there is no need for communication with apis on different domains) then you can (and actually should) store authentication info in an httpOnly cookie. But that can still be a JWT if you want your server application to be stateless. If it is stateful anyway, thenthere is not much point in using a JWT, you could just use a session id and that would be more secure.
If you want stateless though, JWT is a good option as it is widely supported and a standard way to store such info on the client. In a well-known implementation it's typically relatively secure too, so as usual, don't roll your own, otherwise you have to face challenges like properly signing tokens, verifying signatures, avoiding replay attacks and so on. It's more difficult than it may first seem.
Token lifetime should be set based on your business case and the associated risk. It's always a balance, and ultimately your decision. It should be the shortest that works for your product, be it pretty much whatever. You just need to be aware that a compromised token can be used by an attacker until expiry and set it accordingly.
A refresh token only makes sense if it is stored differently. If it's your javascript storing and accessing the refresh token too, there is no point, it will be compromised the same way. However, you could do something like a login service or endpoint that creates a long-lived refresh token, stores it in a httpOnly cookie, and creates a short-lived JWT for actual use. Whenever the JWT expires, your javascript can go the the login endpoint and get another JWT with the cookie until the refresh token expires too. This would make sense, because an attacker could only access short-lived JWTs via XSS, and the refresh token would be a little more secure. But this way, it is slowly evolving into a single sign-on-ish thing, for which you should (again) use a standard algorithm and implementation, like for example OpenID Connect, which has free implementations too.
Upvotes: 1