I am setting up auth using access tokens and refresh tokens. I am largely there, but I am having trouble understanding how to refresh the access token. From what I have seen from here and other resources, most people seem to set up route handlers to refresh the token like so:
#UseGuards(JwtRefreshGuard)
#Get('/refresh')
refresh(#GetUser() user: User) {
return this.authService.getAccessToken(user.username);
I am using a custom guard using a passport strategy to validate the refresh token:
async validate(request: Request, payload: JwtPayload) {
const { username } = payload;
const refreshToken = request.cookies?.Refresh;
return this.userService.getUserIfRefreshTokenMatches(
refreshToken,
username,
);
What I am not understanding is how to implement making a request to this handler without interrupting the app user's normal operations, and how to check if this handler needs to be called when an access token expires.
how to check if this handler needs to be called when an access token expires.
When you make a call with jwt token from the client to the server if it is expired(which is the case that we use refresh token) with jsonwebtoken npm package we can send a callback to the client with the message "Jwt expired"(since you are validating the jwt you can identify if it an expired token). Then the client can send another request to your /refresh endpoint on the server requesting a new jwt token. Then you can send the new jwt token from the server to the client and the client can use the newly created jwt to send requests to the protected routes on the server.
On client side you can control access token expires. So, if the access token has 5 minutes of life, and was born 3 minutes ago, then only the access token can be transferred to the backend. But if 10 minutes have passed since the birth of the access token, then the client must first send a refresh token to the backend, and continue to process the current request only after receiving a new access token.
Related
I am trying to understand this access_token, refresh_token feature. And this is what I understood:
-- LOGIN:
CREATES access_token;
CREATES refresh_token, sends to DB;
SENDS refresh_token + access_token to client;
access_token expired:
API automatically CREATES a new access_token, using refresh_token;
refresh_token expired: API DENIES all requests, forcing the client to login again.
And i heard that you need to save the refresh_token on a 'sessions' table of database, or smth like it. But i can't understant why, since the client will/may send the refresh_token on all requests. Making it useless to save to DB.
I don't know if i got anything wrong, i hope you can help me out!
What is a little bit awkward (or unclear) in your example - which system creates access and refresh tokens, and sends them to the customers?
Based on the description, I would conclude that this is the identity provider - the client authenticated themselves and got those tokens as a result.
Now when the client calls an API (on a resource provider), they have to include the access token with each request. The resource provider would take the access token and validate it. If the access token is not valid, the API just have to return "access denied".
The client has to use the refresh token to get the new access token from the identity provider and repeat the call to the API on the resource provider.
This would be the typical usage of the flow.
The other common use case is to allow a backend system to do api calls on behalf of the client - in those cases, the backend system has both access token and refresh token; so it can maintain the logged in state even if the client is not around.
It might be that your example is some kind of hybrid solution - both customer and the backend do some calls to IDP.
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 largely followed this tutorial on how to do client authentication with Google Sign-In, get a JWT, and verify the JWT on the server on each request using Google's tokeninfo endpoint.
Everything works great except the tokens expire after 60 min and I don't know how to refresh the token.
The API server should not be involved in this refresh. The client is responsible for getting a refreshed token from the authentication service (google in this case) but there is no documentation on how to do that that I've found.
What I've observed is that the id_token is actually automatically updated by the gapi library before expires_at passes, usually about 5min before.
authInstance = gapi.auth2.getAuthInstance()
currentUser = authInstance.currentUser.get()
authResponse = currentUser.getAuthResponse()
You can then get the id_token and expired_at by doing:
authResponse.id_token
authResponse.expires_at
You can monitor for this update by doing:
authResponse.listen(function (gUser) {
const jwt = gUser.getAuthResponse().id_token
// ...you now have an updated jwt to send in all future API calls
}
I have the following scenario, in my vertx application I have an endpoint /login that after receiving correct credentials is issuing a JWT with 30 minutes validity.
I use this token to protect all routes under /api/* endpoints.
All of this is working as expected.
My problem is that I want to be able to intercept those /api/* requests and just before doing the token authentication to inspect the token and if it is about to expire to generate a new one that can be returned in the headers of the response so the client can use it on consequent requests.
What I want to achieve is:
avoid issuing forever valid tokens as if leaked I have no way to prevent access to the application
avoid maintaining a token blacklist of anykind
avoid having to issue very short living tokens and reissue those on every request
In general any kind of strategy is welcome.
Thanks
In order to handle a request before the JWT validation all you need to do is add your custom handler before the Auth handler e.g.:
Router router = Router.router(vertx);
// Create a JWT Auth Provider
JWTAuth jwt = JWTAuth.create(vertx, new JsonObject()
.put("keyStore", new JsonObject()
.put("type", "jceks")
.put("path", "keystore.jceks")
.put("password", "secret")));
router.route("/api/*").handler(ctx -> {
// here do what you're planning to achieve, and the call
ctx.next();
});
// protect the API
router.route("/api/*").handler(JWTAuthHandler.create(jwt, "/api/newToken"));
I am reading this blog on how OAuth2 works. It is an excellent source and I guess I have understood the basics of how OAuth2 works.
when reading about Authorization grant, that involves granting access to the Application server (my server) which exchanges the authorization code it received from authorization sever (eg facebook) through the redirect URI registered.
myserver then exchanges this authorization code for access_token and refresh token. when the access token is expired, refresh token is used to get a new access token.
Q1) From this flow, I see that the authorization code given by facebook is used only once from my server to get the access_token. For subsequent requests, this authorization code is not used. Is this correct ?
If the user log-in to my server after 3 days during which the access token has expired, my server will use refresh token to get a new access token and use this access token.
Q2) Does the refresh token expire or each time a refresh token is used to get a new access token, a new refresh token is provided?
Q1) RFC6749, Section 4.1.2 Authorization Response: The client MUST NOT use the authorization code more than once.
Q2) RFC6749, Section 6 Refreshing an Access Token: The authorization server MAY issue a new refresh token, in which case the client MUST discard the old refresh token and replace it with the new refresh token.