To some extent it may depend on the design of your web app and the level of security
your app requires (based on a risk assessment). In short, there is no one answer
suitable for all situations. The key to a good user experience is ensuring your
security level is in-line with the actual requirements. Too stringent security
requirements with too short a timeout will lead to frustration for the user and too
little will expose them to excessive risk.
Understanding how your app is used is very important. Nothing frustrates a user
more than being forced to re-authenticate multiple times in what they consider a
single session. For example, I have some apps which I keep open for a long time, but
I might only actively use the app a few times a day. I don't want to re-authenticate
after every 30 minutes of idle time, but I'm happy to re-authenticate once a
day. Other apps, such as my banking app, I want to ask me for re-authentication if
the session has been idle for just a short period.
I think the most important objective is to make the re-authentication process as
painless as possible. Forcing someone to re-enter their credentials and then sending
them back to the home page is rarely a good solution. What you want is a process
which briefly interrupts the users workflow, but once re-authenticated, puts them
back into their workflow at the point where it was interrupted by the authentication
process.
This can be a little tricky with traditional based applications where much of the
workflow state is maintained on the server - especially if you use session
timeouts. However, it sounds like your application is using a lot of javascript and
so I suspect you maintain local state.
One solution is to have your rest API verify your token/session and if a decision is
made that you need to re-authenticate, pass back json data which essentially tells
your app to re-authenticate than then re-submit the request. Javascript on your
client can then use this information to pop up a modal window to collect
authentication data, submit it to your authentication service to get a new token and
then re-submit the original request with the new token.
for a more traditional application, the general solution is to use server
redirects. When you try to access a REST API and your token has expired, redirect the
browser to the login page, but have the login page also accept a 'next' url. Once the
user is authenticated, the login service will use the next parameter to redirect the
browser back tot he original REST API call. The challenge with this can be ensuring
you maintain all necessary state information.
Another addition which is sometimes acceptable is to have your authentication service
configured so that if it gets an authentication request which includes a token which
is still valid, it does not require the user to re-authenticate. Instead, it just
issues a new token. This will allow your application to renew the token without user
interaction in the background. Your REST API's can be configured to redirect to the
authentication service if the token is going to expire within the next X
seconds/minutes. The advantage of doing this is that if someone has a very long
session, they are not forced to re-enter their credentials simply because the value
you set for token expiration has expired.
Most of the time, the applications I work on do not have high security
requirements. For these applications, I tend to use a long expiration value for the
tokens and a reasonable session expiration timeout based on idle time. This way, the
user is not forced to re-authenticate simply because of an arbitrary expiration time
for the authentication token, but they are required to re-authenticate if the session
has been idle for a specified amount of time.