Let's say we have a refresh token with a lifetime of a month. Within that month with each subsequent call to the "auth" endpoint(with username and password) should the same refresh token be returned, or should a new one be generated, and why?
Long story short...should the user be forced to log in again after the lifetime of the refresh token expires, or should he be allowed to refresh his tokens indefinitely?
The usual pattern I have seen used is that the initial authentication or refresh call is what would return both a new access token and a new refresh token. One use of the refresh token is for acquiring a new access token after the current/old access token has expired. Here is an example workflow:
user authenticates via 1FA/2FA to the server
access and refresh tokens are returned; refresh token lives slightly longer than access token, by design
after some time, the access token expires, and the user sends the refresh token to the server
a new access and refresh token are returned, continue from the second step above
As the refresh token intentionally will outlive the access token, there is no need to send a new refresh token with each request. Rather, simply let the user initiate the request for a new access/refresh token when the time comes.
Related
After doing some research in using JWT with Access Token and Refresh Token for authentication. I understand this in this way.
After login, return to user Access Token and Refresh Token (using same technique JWT for both).
Saving Refresh Token in Database (one User can have multiple Refresh Tokens for multiple devices).
Whenever user sends a request with invalid Access Token, check Refresh Token and call another api to get new Access Token (doing this in client side). After that, call api to get data again with new Access Token.
If Refresh Token is invalid, deleting its record in database and user must to login again to get new Refresh Token.
Does I understand Access and Refresh Token technique correctly? Please give me some advices. Thank in advance.
Of the 4 steps you listed, some look more or less correct while others do not. I will begin this answer by giving the premise for why refresh tokens were created and what is their main purpose.
Using the JWT pattern with only access tokens, there is a potential usability problem when the JWT token expires. Consider as an example a banking website. When a user logs in, he receives a JWT token with a certain expiry (typically stored under the exp key in the claims section of the token). If the token is given say a 5 minute expiry, then from a usability point of view, it means that the website would have to force the user to manually login every 5 minutes. Obviously, this is not the best user experience, because it means that a user who happens to be in the middle of some business process when the token expires might lose all that work. This is where refresh tokens step in to alleviate this problem.
Using the JWT pattern with refresh tokens means that the user receives both an access and a refresh token. A typical workflow here might be:
After login, return to user Access Token and Refresh Token (using same technique JWT for both). The receiver notes when the access token is set to expire (say 15 minutes).
As the expiry of the access token approaches (e.g. 10 minutes), the UI will send the refresh token to the backend to obtain a new access token (and refresh token). This could be done explicitly, e.g. on a website which displays a popup asking if the user wants to continue. Or it could be done in stealth mode, with a REST call being made under the hood to get the new access token.
For the edge case where the refresh token cannot be used to obtain a new access token, then the very next user action which requires authentication would fail. In this case, the user would have to redirected to the login page. But, as this case should generally be rare, it does not disqualify the refresh token pattern.
I would also point out that storing the access/refresh tokens in the database largely defeats the purpose of the JWT pattern. One major reason for using JWT is that it pushes the user session state out of the application and onto the user. By storing tokens in your database, you are totally making your user sessions very stateful, which has all sorts of potential drawbacks. Consider using the suggested workflow above to avoid doing this.
The way I see it, your refresh token needs to be stored and associated with the device and the user.
Example:
User Logs In in Device A
Call Login endpoint
Validate user is valid
If valid, generate a refresh token associated with the userid & device
id
store required data to your table or storage engine (user_sessions..etc)
user_id | device_id | refresh_token | expires_at
Return the payload with access_token, refresh_token , access_token_expires_at, refresh_token_expires_at
Front-end, store the payload
when consuming a resource, check the following
If refresh_token_expires_at > now then logs them out , show your session is timeout (or you can have a never expired refresh_token.. ex. refresh_token_expires_at can be 0)
if access_token_expires_at > now then call refresh token endpoint along with your payload.
on the refresh endpoint, validate the call and check the refresh token against the data stored.
if refresh token is valid for this user+device, generate a new access_token
return the access_token and its expires_at
If the refresh token is INvalid , return invalid
front end will log the user out.
** in any case, if a refresh token was compromised, it will be only for that particular device/user. A user can then deactivate or remove the device from their list. This action will invalidate the refresh_token on their next refresh call.
Trying to use Salesforce OCAPI from an app.
On the JWT Auth documentation: https://documentation.b2c.commercecloud.salesforce.com/DOC2/index.jsp?topic=%2Fcom.demandware.dochelp%2FOCAPI%2Fcurrent%2Fusage%2FJWT.html
A JWT has a lifetime of 30 minutes. Before the token expires, you must exchange it for a new token if you want to extend the total lifetime.
If a registered user opens the app after 31 minutes and the persisted JWT is expired, then how is the way to refresh it without prompting login screen again? (persisting user credentials is out of the question due to security vulnerability)
As the documentation states, you cannot refresh it if it has expired. You must prompt for the login screen again.
I suggest having your app refresh the token automatically in the background.
You can save exp (the token expiration-time) from payload section in your db, try to check before intiatling new call if its expire then you can use the /customers/auth resource to get new token. You must include the current token in the Authentication:Bearer request header, and specify the customer type as "type":"refresh".
Keycloak refresh token expiry is tied to SSO timeouts. If SSO Session Idle is set to 30 minutes, the refresh token will only work for 30 minutes. Session Idle can only be as large as Session Max, therefore the lowest of both is taken as the max refresh token life. How to specify the Refresh token expiry separately as we have for the access token? If the refresh token expires do we need to get another refresh token. Ideal refresh token expiry time?
A client application uses the refresh token to get a new access token without user interaction. It should do so before, or shortly after the access token expires. It will then receive a refresh token which is again valid for 30 minutes (Keycloak Session Idle Timeout). The client can repeat until the Session Max timespan is over.
As a client don't let the refresh token expire:
If the refresh token has expired, the client needs to direct the browser to the authorization endpoint. To prevent this, your application should use the refresh token when the access token gets invalid. Even better: Schedule a refresh for the time before the access token expires.
Scope offline access
As an alternative, the client could request scope "offline access". In this case, the refresh token lifetime is not bound to the SSO Session idle and Max settings.
For details see https://www.keycloak.org/docs/latest/server_admin/index.html#_offline-access
i'm currently developing a multiplayer turn base card game with Unity. The multiplayer architecture will be using websocket (NodeJS Socket.IO) and for the security wise, i'm using JWT with refresh token after access token expired.
Everytime when i emit a request to websocket, i will emit the request along with the access token. By right when the access token has expired, i should revoke a new access token with refresh token. My concern here is the refresh token handling. Should i emit request back to client for getting the refresh token and re-emit the refresh token back to websocket to renew the access token? To renew the access token, I will validate the refresh token through Database to make sure the token is valid. I am wondering the entire process is appropriate and causing any delay(lagging) since it is real-time multiplayer game.
Anyone here able to give some advice?
If you see a traditional HTTP API which is authenticated based on an access/refresh token, the application tracks the expiry time of the token on its own (this means JWT should have an exp timestamp). If the application detects the access token is about to be expired, it fetches as a new one from the server exchanging the refresh token.
Same flow holds valid here
Check the expiry timestamp with current timestamp (minus some buffer time).
If the access token is about to expire, get a new one from the server and proceed with the previous call.
I'm beginning a Single Page Application, and I'm using JSON Web Tokens to Authenticate client side (JS Client with Server API).
In my app, user provides credentials (app auth, facebook, google) and then server checks for user existence and returns a token.
Client JS adds token to each request in order to use the Server API.
When token gets issued, it has an expiry time and a max refresh time. If a set a short expiration time for the token and a "good" max refresh time I get into having to know when to refresh tokens. Best approach I've found so far, is to check on client when the token is being expired (5 minutes before) and then issue a refresh request. Then I'd get a new token. This could be done till max refresh time is reached. Then, user should have to reauthenticate.
Another approach I've seen, is that on server, if token is nearly or has just expired, it gets auto-refreshed and returned to client (which has to detect token change and store it)
But... what is the difference between this and having a single token that is long lived?
Is having a short lived access token which can be renewed with a refresh token tons of times better than having a single long lived access token?
The primary reason to use a short-lived token is to defend against session hijacking, when an adversary, through one method or another, steals session credentials (in this case, the token) and acts maliciously in the victim's session. The shorter-lived the token, the less time the attacker has to carry out whatever malicious activity they have planned.