Refresh expired jwt in browser when using Google Sign-In for Websites - jwt

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
}

Related

Why is it needed to save the refresh token in the database?

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.

Do you need to use the OAuth flow to access your own dropbox account?

I'm writing a dropbox integration against my own account. When file get dropped I respond to a webhook notification and import the files into one of our backend systems.
It's all done in back end server code and there is no real opportunity to pop up a UI to get me to sign in.
I've developed it so far using the access token you can get from the app console but that expires after a few hours.
Are there any auth shortcuts when using the API with just your own account?
I've figured out some shortcuts for myself
First off all as its a background process it needs to be running with "offline" access and using refresh tokens to acquire short lived access tokens.
As there is no UI and its only for my own account I can get an authorisation code via the browser from this URL
https://www.dropbox.com/oauth2/authorize?client_id={{Your APP ID Here}}&token_access_type=offline&response_type=code
then use POSTMAN to get an access Token & Refresh Token:
In Postman:
Post to https://api.dropboxapi.com/oauth2/token
Authorisation Basic
UserName = {{AppKey}}
Password = {{AppSecret}}
Body :x-ww-form-urlencoded
code = <<Auth Code From Browser>>
grant_type = authorization_code
This produces a result with an access_token and a refresh_token
The refresh token will only expire if I withdraw access so that will be safe to add into my config and use to request access tokens or connect to the client.
In my case its c#
using (var dbx = new DropboxClient(refreshToken,appKey,appSecret))
{
var myAccount = await dbx.Users.GetCurrentAccountAsync();
String.Format("{0} - {1}",
myAccount.Name.DisplayName,
myAccount.Email)
.Dump("Account Details");
}

Refreshing a JWT Access Token using JWT Refresh Tokens and NestJS

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.

Nodemailer no refresh token or refresh handler callback is set error

The email sending works within the first day of getting the refresh token. However it always fails a few days later and it will work again when i regenerate a new refresh token in OAuth 2.0 playground.
I have already put in the refresh token here which is obtained from OAuth playground!
const oAuth2Client = new google.auth.OAuth2(
CLIENT_ID,
CLIENT_SECRET,
REDIRECT_URI
);
oAuth2Client.setCredentials({ refresh_token: REFRESH_TOKEN });
google.options({ auth: oAuth2Client }); // Apply the settings globally
First off if you are creating the refresh token via the OAuth 2.0 playground using the default credetinals the tokens are only going to last a few days at most OAuth 2.0 playground is only meant for testing it should not be something you should be relying upon.
Second if you are using your own client id and client secret same goes. OAuth 2.0 playground. should not be used for applications its just for testing you should fix your code sot hat you request or own refresh token and access token.
That being said if your application is still in testing the refresh tokens only last seven days and then they will be revoked.
Your application should be able to handle the refresh tokens expiring and request a new one of the user.

is the Authorization code in OAuth 2 is used only once for the lifetime of the client Application running server?

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.