User Experience Problems with JWTs
Ryan Chenkie: [0:00] Where we left off from the React Security Fundamentals course, is that we've got this application that has authentication applied to it now, so users can log in and sign up. Only after they have authenticated, can they get over to the dashboard and see data here. Then, only admin users can get to areas like the inventory area.
[0:19] We have a fully authenticated app with the data coming from a protected API, but there are still some issues with this application that we should smooth out. Most of those issues have to do with the user experience that this application gives when it comes to authentication.
[0:34] In particular, right now, there's nothing in this application that will get a new JSON Web Token for the user when their token has expired. Right now, we've built in some logic that is going to kick the user out after their token has expired.
[0:48] We've got a pretty short expiry window on our tokens. If we take a look in Orbit API and then go into util, this is where our tokens get created. We're saying that we want them to expire after only one hour.
[1:00] The experience then that the user is going to have is that they'll be working in the application and after an hour passes, if they try to do something like create a new item or read some data, they're just going to be logged out of the application.
[1:14] We can give ourselves a sense of what this looks like, if we come over here, and we reduce the token lifetime to something like five seconds. Let's save that and then, let's log out of the application, and we'll log back in.
[1:29] We get over to the dashboard, and then, after five seconds have passed, if we try to go to another area to read some more data, were just kicked back over to the home page. That's because we experienced a 401 error coming from the back-end.
[1:43] Let's look at that one more time, we can log in again. We get a good authentication, we get a good call to dashboard data, but after only five seconds, if we go to get some other data before we even go to call the data, our application knows that the user should be logged out. The reason it knows the user should be logged out, is that we've got this check in here called isAuthenticated.
[2:06] In the Orbit app into Source Context and then, AuthContext, we've got this function here called isAuthenticated. This is looking at the current time, and it's comparing it to the expiry time of the JSON Web Token.
[2:20] We're saying if the user's JSON Web Token has expired, it won't be of any use to them in the application anymore, so we should log them out. As we can see, that's not a very good user experience as it stands.
[2:32] Now, even if we didn't have this isAuthenticated function doing the work that it's doing right now. For example, if we just comment that out and then, we return true, and then, we come back to the application, and we log in again, what we're getting is a 401.
[2:48] We got that 401, because our token has expired. The isAuthenticated check didn't do the work that it used to do when we went to click Login, so we just got over to the dashboard.
[2:57] We can see the effects of this. If we do a fresh login, so let's log out. That gets us back over to the login screen, and we can log in one more time. Once we do we get our data. We get a good call for dashboard data, but once again, after five seconds have passed, if we go to get some other data, we'll get a 401.
[3:17] We're no longer being kicked out of the application, but we're also not getting the data that should be there. The problem right now, if we were to sum it up, is that the application doesn't have any logic right now to go and get a new JSON Web Token when the current one has expired for the user.
[3:33] If we don't have that kind of logic in place, it leaves us with only one option, and that is to create a long token lifetime. If we want to provide a decent user experience, then we might want to provide something like 12 hours here for our token or maybe even 24 hours.
[3:51] Now, the problem with doing this is that the longer are tokens live for the more risk is carried in our application, because if someone is able to get hold of a user's JSON Web Token, that token can be used to access data from our API without us knowing about it. A best practice is to keep token lifetimes as short as possible.
[4:11] The value here that we've had up until now that has been one hour, that's a decently short token lifetime. However, like we've just seen, the problem is that we don't get a good user experience with that.
[4:22] One solution to this problem is to periodically refresh our JSON Web Tokens, and we can do that with something called Refresh Tokens. Our goal in this module is going to be to implement token refreshing and then, provide a much better user experience here.