How to get a new access token via refresh token using Expo Auth Session? - react-native

I'm using Google for auth (expo-auth-session/providers/google)
I can successfully login for the first time and fetch an access token and a refresh token. The refresh token will get stored in SecureStorage.
Now at this point, when the old access token is invalidated, I need to use the refresh token to get a new access token, but Expo's docs don't really provide any guidance on this part. I have checked their API quite thoroughly, but can't see anything that helps me retrieve a new access token with a refresh token.
Any guidance would be welcome.

The AuthSession library has a method specifically for refreshing tokens. It requires the clientId used to retrieve the token initially, so you can reuse that, the refreshToken which you have stored as well as a token endpoint.
const tokenResult = await AuthSession.refreshAsync({
clientId: "<your-client-id>>",
refreshToken: "<your-refresh-token>",
}, {
tokenEndpoint: "www.googleapis.com/oauth2/v4/token",
},
);
I wasn't able to test this myself as we use firebase and useIdTokenAuthRequest as a result, so I wasn't able to get my hands on a refreshToken to run it through that function - but the documentation of that method seems pretty solid.

Related

When to update JWT access token with refresh token

I made a Quasar App with an external authentification server. After the login I receive the access and refresh token. The refresh token is not expiring until I press logout. The access token expires after 10 minutes. So since I need the access token to get the data, this is possible for the next 10 minutes after login. Afterwards I have to call an API including the refresh token to get a new access token.
My question is, how can I make sure to always have a valid access token without logging in again?
As a User I expect to login and have access to everything until I logout. And if my App was for example 15 minutes just laying around and then I want to receive data, that's not possible.
Somehow I want to call the refresh token api silently, but when and how?
Is it common to refresh the token at a certain time interval, or on changing a page or every time I want to receive data?
I didn't find an efficient solution yet.
In a boot file I added the refresh token method. So every time the App was started, the token will be refreshed. For iPhone users for example the app won't be closed completely so the init-method will not be triggered until I completely close the App manually.
I guess to refresh the token before every API call is too much. Or is it?
My question is, how can I make sure to always have a valid access
token without logging in again?
You may use Axios response interceptors in the Quasar Axios boot file to check if a response has failed due to expired access token (based on status code eg 401).
axios.interceptors.response.use(
(response) => {
return res;
},
async(error) => {
if (error.response) {
if (error.response.status === 401) {
// Use refresh token here to get new JWT token;
// return a request
return axios_instance(config);
}
}
return Promise.reject(error);
}
);
Hope this helps!

blacklisting/validating/generating JWT Refresh Tokens

I issue an access token along with a refresh token upon successful login. They are both saved in same site cookies in the browser. A custom middleware will put the token in Authorization header before the authentication process. This middleware will also check if the access token is expired, if it is it will try the refresh token, if validated it will save two new cookies(the new refresh token and new access token) and pass the new generated access token with the current request.
Is this how we are supposed to implement refresh tokens? If I want to blacklist a specific refresh token, should i save all refresh tokens in the database?
string auth = httpContext.Request.Cookies["AuthToken"];
if(string.IsNullOrEmpty(auth))
{
httpContext.Request.Headers.Add("Authorization", $"AuthorizationCookieNotFound");
return _next(httpContext); //That token wont be accepted i just
// put it there for the sake of demonstration
}
httpContext.Request.Headers.Add("Authorization", $"Bearer {auth}");
return _next(httpContext);
You have to be very careful while storing refresh tokens and they must be kept at some secret place otherwise you know the consequences.
I assume you are using "Aurhorization Code flow" here. So it's a good idea to store the refresh tokens in the db against the username and you can add an extra column e.g "IsRevoked" for status purpose and then you can blacklist/whitelist the tokens basked on the username and isrevoked status.
See this link about storing tokens.

best practices for refreshing access tokens automatically

I'm building a react native app which uses the spotify web api. I'm using the authorization code flow to authorize a user. First I get a authorization code which can be used to obtain an access token and a refresh token. Everything works!
The problem is: an access token is only valid for a limited amount of time. That's where the refresh token comes in. I understand this concept, but I'm breaking my head about how to implement this.
Let's say a users opens the app, requests an access token and uses this for some time. Then, the user closes the app. After 15 minutes, the users opens the app again. The access token has now expired, so I need to request a new access token.
I've come op with several "solutions". Can someone point me to the correct solution?
Solution 1:
Every time the user opens the app, I request a new access token and use this. Problem: when the user uses the app longer than the valid time of the access token, I won't work anymore.
Solution 2:
I use the access token that's stored in the secure storage on every request. When a request comes back with 'access token invalid' (I don't know the exact error code but you guys know what I mean), I request a new access token with the stored refresh token, and then I send the previous command again (with the new access token). But my question here is: can I use some kind of "wrapper function" which checks the response of the request, and if the response is "access token invalid", it automatically requests a new access token and runs the previous request again.
I think certainly correct solution is solution 2,and i think its clear enough.
and for using solution 2 you need somthing like wrapper function,yes its intelligently.
so you should use interceptor:
what is interceptor ?
You can intercept requests or responses before they are handled by then or catch.
in link below there is a good example of implementing refresh token in axios interceptor:
https://gist.github.com/Godofbrowser/bf118322301af3fc334437c683887c5f
I agree that Solution 2 is the best, each time you do a request you can check to see if the Access Token has expired, and if it has then you can request a new Access Token using the Refresh Token as you mentioned and then make your request, in my own project I do this in a FormatRequestHeadersAsync method which calls a CheckAndRenewTokenAsync method where I perform the following check, here shown in C#:
if(AccessToken?.Refresh != null && (AccessToken.Expiration < DateTime.UtcNow))
{
AccessToken = await GetRefreshTokenAsync(
AccessToken.Refresh,
AccessToken.TokenType,
cancellationToken);
}
You can store the Access Token and the Refresh Token and then use something similar to this before you make each request to the API this will refresh your token and then you can store the new Access Token and the existing Refresh Token.

Why Google OAuth Api Refreshes Token?

I am trying to get the Access Token using google oauth 2.0 but whenever i login again it goes through the consent screen process and generates a new token.
Is there any way to get same token until the token expires? or(2)
How to stop google from asking to allow to access scopes, if the user has accepted/allowed once.
This is how i am getting the access token.
Uri.https("accounts.google.com", '/o/oauth2/auth', {
'response_type': 'code',
'client_id': identifier,
'redirect_uri': '$REDIRECTURL',
'scope': 'https://www.googleapis.com/auth/youtube.readonly',
});
then:
response = await http.post("https://oauth2.googleapis.com/token", body: {
'client_id': identifier,
'redirect_uri': '$REDIRECTURL',
'grant_type': 'authorization_code',
'code': code,
});
I'm afraid that's how tokens work: whenever you ask one, you get a fresh one. Just store the access and refresh token (needed to refresh the access token when it expires) on your side and don't initiate the OAuth if it's not needed.
There are parameters setApprovalPrompt = auto / force
Force will cause that it will ask access scopes every time.
Auto won't ask, but you will not get "refresh_token" if you already received it before, and you only get "access_token" that is valid for 1 hour

Issuing authenticated queries with Graphcool

I have successfully set up Graph.cool Auth0 authentication and created a User through Relay as described here.
Next I'd like to actually query graph.cool on behalf of this user. As a first step, I simply manually modified the Relay setup to specify the same auth token as was used to create the User in the first place (through the idToken on type AUTH_PROVIDER_AUTH0):
Relay.injectNetworkLayer(
new Relay.DefaultNetworkLayer(process.env.GRAPHQL_ENDPOINT, {
headers: {
Authorization: 'Bearer XXX.YYY.ZZZ',
},
})
);
However, the app stops rendering and I just get a console warning RelayPendingQueryTracker.js:153 Server response was missing for query Index. Any hints?
When calling the signinUser or createUser mutation, a Graphcool token is returned in the payload. https://www.graph.cool/docs/faq/graphcool-session-user-goij0cooqu
This is the token you need to use in the Authorization header instead of the Auth0 idToken.
Maybe it can also be a help to take a look at how we do it in the dashboard https://github.com/graphcool/dashboard/blob/master/src/views/LoginView/LoginView.tsx
Hope this helps!