Plaid - error_code: 'ITEM_LOGIN_REQUIRED'. Recurring every hour or so - plaid

I am getting the following response when calling the /accounts/balances/get endpoint in the development environment. After getting this, I'll use update mode to get a new access_token. Once I swap in the new token, everything works fine for about an hour and then this error will occur again. I am 100% not making any updates on the bank side.
{ display_message: null,
error_code: 'ITEM_LOGIN_REQUIRED',
error_message: 'the login details of this item have changed (credentials, MFA, or required user action) and a user login is required to update this information. use Link's update mode to restore the item to a good state',
error_type: 'ITEM_ERROR',
request_id: 'redacted',
suggested_action: null }

Does the login associated with the Item have "perpetual OTP" enabled -- i.e., is it configured so that you need to enter a 2-factor authentication token every time you log in to your bank, even on a trusted device?
If so, this is expected behavior -- once your original session expires, Plaid requires a user to be present to provide a new token and create a new session to get fresh data.
If not, there may be an issue with the integration between Plaid and the specific financial institution. If that's the situation, you should file a support ticket with Plaid so we can investigate further.

Related

my app is not able to receive refresh token from Google anymore

i have a very weird problem. I'm using the Google authentication API since moree than one month now and all working perfect. But now out of the sudden, my users can't get refresh token anymore. My app is on testing state, so i thought the refreesh token my testing user was having is expired after 7 days, but then i tried to get another refresh token by doing thee authorization from the beginning to receive a code that i use to get a refresh tokn. But no chance i'm only receiving this response back: Status code 400 { "error": "invalid_grant", "error_description": "Bad Request" }
Thank you very much for your help!
A Google Cloud Platform project with an OAuth consent screen configured for an external user type and a publishing status of "Testing" is issued a refresh token expiring in 7 days.
To stop your refresh tokens from expiring set it to production.
Why cant you refresh after seven days
What i am writing here is my opinion only from experience. There is no documented proof of any of this from googles side.
After seven days your refresh token will expire, but the question is how is google expiring these refresh tokens. From what i can see they are not using the normal method of expiring the refresh token. They are in fact revoking the users granted access on the google account. So the all of the refresh tokens granted will stop working at once.
So why are you having issues with the client library. Normally the way the client libraries were originally designed. if the refresh token expired it would prompt the user to authorize the app again. This does not happen with the seven day revoke method. IMO because the error message is different, and the libraries have not been updated to take this into account, and prompt for access again. The only way to fix it is to delete the old stored refresh token and request a new one.
So your not able to receive new refresh tokens because your code is stuck with the old one. Make sure to hard delete any old refresh tokens you have stored. They wont work and the library doesnt understand how to delete them on its own.

I want to use Google API refresh tokens forever

There is a process to obtain a refresh token via OAuth authentication for Google API, and then obtain an access token from the refresh token to validate the receipt.
The other day the refresh token suddenly expired and the receipt validation failed. Our service stopped processing billing.
Below is the error when it failed.
{
"error": "invalid_grant",
"error_description": "Token has been expired or revoked."
}
I thought refresh tokens reset their expiration date each time they are used, so why did they expire?
I don't think the following rules apply.
You must write your code to anticipate the possibility that a granted refresh token might no longer work. these reasons:
The user has revoked your app's access.
The refresh token has not been used for six months.
The user changed passwords and the refresh token contains Gmail scopes.
The user account has exceeded a maximum number of granted (live) refresh tokens.
The user belongs to a Google Cloud Platform organization that has session control policies in effect.
(https://developers.google.com/identity/protocols/oauth2)
I want to use the refresh token forever.
Thank you in advance.
Refresh tokens do not expire by design there are a few things that can cause them to expire as you have listed. However there is one you have not listed.
If you check the docs for Experation you will find it also says.
If your app is in testing set it to production and your refresh token will stop expiring.
So as long as your app is in production, the user does not revoke your access, and they have less then 50 outstanding refresh tokens for that user, and you have used it at least once in the last six months. (gmail scope the user does not change their password). The refresh token should not be expiring.
That being said your system should be designed to handle a refresh token expiring and request access of the user again. or notifying the admin if this is a backend system.
Thank you for this interesting conversation. It looks like in my case, after having got an access_token and a refresh_token, which I use regulary to invoke the Gmail API, it no longer works after 6 months.
Could someone point me to a code example in Node, showing how to update the tokens on a regular basis? (I store them in a database, and wonder how to update the record appropriately via the google.auth.OAuth2 API).
I have made hundreds of searches but could not find anything else than "you should refresh your tokens" :)
It looks like
oauth2Client.on('tokens', (tokens) => {
logger.info("tokens=%o", tokens)
})
is only invoked once when establishing the connection, so it will not help.
I have also tried:
let x = await oauth2Client.refreshToken(database_refresh_token)
let refreshedToken = x.tokens.access_token
To store the new refreshed token in the database, but this does not help after 6 months. FYI, thanks to oauth2Client.getTokenInfo(refreshedToken) I can see that refreshedToken expires in 1 hour.
Finally, is there a way to test, without having to wait for 6 months?
Many thanks!
By last answer...
It means we can used one refresh token for 6 month. right ?
And after 6 month we have to update refresh token. right ?

Server-to-server Facebook Access Token expires

I am building an Integration that allows users to schedule creation of Custom Audiences on the Facebook Ads platform. Once the user authenticates, we pass the client side token to the server from the client and then exchange their short lived token with the ads_management permission for a long-lived token, but that token only lasts 60 days?
The idea of the integration is that the user can set it and forget it (but disconnect any time). Now it seems like they need to visit the app at least once every 60 days. Is there any way around this? In my app, the person who turns on the Integration might not necessarily visit the app, or could leave the company and the integration would then break in 60 days.
You can simply ask Facebook for a new access token by passing your current access token.
It's as easy as exchanging the long-lived token, just re-call the same operation (using the current long-lived token). You will get a new one.
I suggest doing so some days before it expires (say, 10 days). This will ensure your system is going to have a spare time if any error occurs (e.g. Facebook's server down, User rejected permissions on your app, ...).
Just like Michael Hirschler said in his answer, you can simply use the old (non-expired) access token to fetch a new one. You should save the expiry date returned on every request when getting an access token: (This property is called expires_in)
{
"access_token":"{long-lived-user-access-token}",
"token_type": "bearer",
"expires_in": 5183944 //The number of seconds until the token expires
}
When expiration date is almost reached, you can use the same api endpoint for that with some changed query params. Insert your old access token as the user-access-token.
curl -i -X GET "https://graph.facebook.com/{graph-api-version}/oauth/access_token?
grant_type=fb_exchange_token
client_id={app-id}&
client_secret={app-secret}&
fb_exchange_token={user-access-token}"
As you can see, you will also need your app-id and app-secret for doing so.
Further reading: https://developers.facebook.com/docs/facebook-login/access-tokens/refreshing/

Refreshing user facebook tokens

I have an application in rails which is heavily based on facebook oauth2. At a glance - user signs in with FB connect and can list it's pages (and do some stuff with that data but that's not important right now. Let's just focus on signing-in and getting pages list).
After a sign-in, i'm saving user access_token and expires_at in the db. Then, each time i need to make a request to facebook api as a user (to obtain his pages list), i'm checking if expires_at is not past and if it is, i'm renewing user token using a following snippet:
def refresh_facebook_token
# Checks the saved expiry time against the current time
return unless facebook_token_expired?
# Get the new token
new_token = facebook_oauth.exchange_access_token_info(
old_access_token)
# Save the new token and its expiry over the old one
self.facebook_auth = {
uid: uid,
access_token: new_token['access_token'],
expires_at: Time.now + new_token['expires'].to_i
}
save
end
This works most of the times but, from time to time, my code throws:
type: OAuthException, code: 190, error_subcode: 460, message: Error validating access token: Session does not match current stored session. This may be because the user changed the password since the time the session was created or Facebook has changed the session for security reasons. [HTTP 400]
in line with exchange_access_token_info.
That error is thrown fo my own user and i can say that i didn't changed the password so i'm not sure what's that caused by nor how can i deal with refreshing the tokens by backend in a bullet-proof way.
Any help much appreciated!
First of all, I would recommend you go through this link and decide which configuration makes sense for your application - using short-lived or long-lived or what.
Now, am not too sure but I think that you are considering the method exchange_access_token_info as the token refresher. If so, this is NOT the case! Once a token is expired, it's useless.
exchange_access_token_info method simply takes the short-lived token (which is currently active) and convert it into the long-lived token using app id and secret.
Just understand that-
The user access token cannot be extended infinitely again and again without any user's interaction with your app for 60 days.
So the flow is very simple-
you get the short-lived token when user authenticates your app (user engagement on front-end)
on server-side you extend the token's validity to 60 days.
want to extend the token validity again? - repeat the steps.
Hope that helps!

How to persist session data in an AngularJS application?

I have this web app written in AngularJs that uses cookies to authenticate the requests in a REST API.
Once the user logs in, the cookie is received and saved in the browser and all subsequent requests send the cookie along to the server. There is a 'User' service/object that saves the isLoggedIn and username values (for UI display/flow). Now, if I refresh the 'index' page, the app restarts. This means that my 'User' object will be cleared. I can check the existence of the cookie and, if it exists, I can re-set the User.isLoggeIn as true and go from there, but I still need to get the username, id, etc. So, my question is: should I create some sort of 'ping' endpoint in the API to verify if a cookie is valid? And if so, the API would send me back the user id and username... OR should I persist the user data in LocalStorage (or some similar cross-browser thing) and just assume the user is logged if the cookie exists? Any other subsequent requests to pages that need authentication would be automatically verified. So, this question really only applies to the scenario where the user refreshes the index page - hence, restarting the web app. I want to know the user data because I want to show a 'user homepage' instead of the 'public homepage'.
What do you think?
You should depend on the server for this. Creating something like GetCurrentUser method on the server. If the user is logged on this returns all the properties of the user.
You should even use this server api to get the user data after authentication completes. So the authentication become two step process first the user is authenticated, on success another call is made to server to get current users details.
Using client side local storage for this would not be ideal because you need to do lot of book keeping, in terms of cleaning the logged in user on log out or session expiration.
Also cookies from server would have expiration times an all, and making decision just based on cookie existing on local storage may not be optimal approach.

Resources