I have two wars: app.war
(struts web app) and rest.war
(classic rest api).
app.war
access rest.war
by jwt token which is generated once user login app.war
successful.
When user use a.war
, some data need to be got from rest.war
by sending ajax calls from jsp of a.war
with jwt token.
The expired time of jwt token is 15 mins, while session timeout of app.war
is 1 hour.
However, if jwt token is expired, there is pop up ask for user login again even and user still can access app.war
.
There is one alternative: use access_token
and refresh_token
, if access_token
expired, then use refresh_token
to get new access_token
and refresh_token
.
For this approach, I have some questions:
First, Why use two tokens? because i think they are the same, just refresh_token
live longer than access_token
and use refresh_token
to get new access_token
, so why not just access_token
and set its expired time longer?
Second, is it same algorithms to generate access_token
and refresh_token
, just their expired is different?
Third, if client perform several api invocations (sync & async) using the token, how handle if one of that invocations return the 401 (token expired) ?
As you said, refresh_token is the recommended alternative to deal with jwt expiration.
Because the use of two tokens (access_token and refresh_token) is a verified strategy used by world class companies (google, azure, amazon, etc) which trust in The OAuth 2.0 Authorization Framework
Which is a product of the Internet Engineering Task Force (IETF) which in turn is : The Internet Engineering Task Force (IETF) is an open standards organization, which develops and promotes voluntary Internet standards, in particular the standards that comprise the Internet protocol suite.
You can use the oauth2 framework rigidly complying its specification, create and hybrid focus on your custom requirements or develop a new framework with new concepts
Oauth2 spec does not recommend a non-expirable token. Token word itself mean a expirable thing. If it doesn't expire, we could use a password.
For example let's imagine a mobile app which needs a token to download some user information. If token does not expire, a thief could steal the mobile app, enter and access to the user info. But as token means expiration, the thief could have a time limited access. Also token could be revoked by the user at the steal time, so the thief could not has access.
Commonly when token expire, a login is forced. But there some requirements in which user doesn't want to login and login again every 3600 ms. So refresh_token helps to don't disturb to our user and get a new access_token without human login. Now, what happen if refresh_token didn't expire? Can we create access-tokens from months or years? That is why refresh_token must expire too
I implemented a kind of security server and I used the same algorithm with different expiration. But I added a extra claim to to differentiate them:
In this case, if token is renewed at every user login, you will have an access_token ready to use with 3600ms of life.
After that your user is kind of robot ( or is a feature/requirement of your web ) and start to use multiple forms which perform several invocations to your rest api attaching the access_token.
If we are in the 3601ms, in the next api invocation from web, the api must return a 403 error and show a classic popup: Session expired, click here to login again...
If your requirement is avoid this popup, you could choice one of these approaches:
Perform access_token and refresh_token exchange in your backend layer, not in frontend (ajax) layer.
So the attackers will never know your endpoint to get tokens or refresh them.