FAILED_PRECONDITION error while hitting the Google people API to retrieve contacts - google-people-api

We are working on a contact sync solution to be able to sync contacts from Google contacts to other apps.
We are using a polling mechanism that runs the people.connections.list endpoint every 5 mins to retrieve the latest created/updated contacts. After we retrieve any data from the above endpoint, we use the refreshed syncToken (nextSyncToken) in our next API call.
We are getting a 400 error with a message Sync token is expired. Clear local cache and retry call without the sync token. before the expiry of the syncToken. I am aware of the syncToken validity period being 7days. But I sometimes experience this issue on the same day after retrieving the new syncToken.
Am I missing any hidden API limitations from the Google People API?
{"error": {
"code": 400,
"message": "Sync token is expired. Clear local cache and retry call without the sync token.",
"status": "FAILED_PRECONDITION"}}

Related

error: invalid_grant , for getting access token using refresh token

After googling we came to know that invalid_grant which means refresh token is invalid.
Link to google oauth doc
We don't have any of these issues mentioned by google. Is this error related to something else rather than a refresh token.
More Info
We have access to read, write spreadsheet and send gmail
We fetch an access token for each request
Any help would be appreciated.
We're already in production and verified by google
Without seeing the full error message that being
Invalid_grant {Message here}
It is hard to help but from my experience is most often caused by one of the following.
Refresh token expire, app not in production.
There are serval reasons why a refresh token can expire the most common one currently is as follows.
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.
The fix is to go to google developer console on the consent screen and set your application to production, then your refresh token will stop expiring.
invalid_grant: Invalid JWT
{ “error”: “invalid_grant”, “error_description”: “Invalid JWT: Token must be a short-lived token (60 minutes) and in a reasonable timeframe. Check your iat and exp values and use a clock with skew to account for clock differences between systems.” }
Your server’s clock is not in sync with NTP. (Solution: check the server time if its incorrect fix it. )
invalid_grant: Code was already redeemed
Means that you are taking an authentication code that has already been used and trying to get another access token / refresh token for it. Authentication code can only be used once and they do expire so they need to be used quickly.
Invalid_grant: bad request
Normally means that the client id and secrete you are using to refresh the access token. Was not the one that was use to create the refresh token you are using.
Always store most recent refresh token.
Remember to always store the most recent refresh token. You can only have 50 out standing refresh tokens for a single user and the oldest one will expire. Depending upon the language you are using a new refresh token may be returned to you upon a refresh of the access token. Also if you request consent of the user more then once you will get a different refresh token.
User revoked access
If the user revoked your access in their google account, your refresh token will no longer work.
user changed password with gmail scope.
If your refresh token was created with a gmail scope and the user changed their password. your refresh token will be expired.
Links
Oauth2 Rfc docs for invalid_grant error rfc6749
invalid_grant
The provided authorization grant (e.g., authorization
code, resource owner credentials) or refresh token is
invalid, expired, revoked, does not match the redirection
URI used in the authorization request, or was issued to
another client.

Alexa home skill request not reaching lambda function after a while

We have an Alexa home skill developed and is under testing. For the Home devices control
ENVIRONMENT DETAILS:
Alexa Home skill
Lambda functions for the execution
Account linking has been enabled
Once I enable the skill, the skill is getting enabled successfully. Starting discovery of devices and finding the devices. Post that I was able to control the devices as well
But say after an hour. When I come back to the app or the echo devices. If I start controlling the device. it displays server is unresponsive and says something went wrong. Try disabling and enabling your skill. If I do that it works fine for an hour. Again it goes to unresponsiveness.
Did anyone experienced such behavior?
I had the exact same symptoms and the root cause was because we weren't properly providing a refresh token, and our access token had a 1 hour TTL.
From the Alexa Account Linking Debugging Tips page:
Problem: Account linking succeeds, but after some time the customer has to link accounts again
Solution: This usually indicates that Alexa was unable to use the provided refresh token to grab a new access/refresh token pair.
Ensure that the access token time to live (TTL) is more than 5 minutes.
Ensure that your authorization server can successfully refresh the access/refresh token pair when presented with a refresh token by
Alexa.
Ensure that you are not invalidating refresh tokens too early - Alexa may take some time after the access token has expired to refresh
the token, and if your authorization server has already invalidated
the refresh token, Alexa will not be able to refresh the
access/refresh token pair and your customer will have their account
linking disabled.
Does your skill implement EnpointHealth?
If not, it may affect the connectivity status in the app.

Is the Access Token for a Cognito user available serverside?

I'm dealing with the issue of users not explicitly logging out of a web application after use, which is not secure enough for the use case. It is a React app with AWS Amplify and Cognito.
I plan to do this by tracking sessions in a database (I can capture the start or refresh of a session using a Cognito Lambda trigger written in Go on PostAuthentication_Authentication or TokenGeneration_RefreshTokens events), and expiring sessions using GlobalSignOut after a period of inactivity, but in order to invalidate the user refresh tokens on session abandonment, I need the Access Token, which appears to only be available to the client.
I can get this explicitly on login from the web client, and post it back to the database using GraphQL to record it, but I was surprised to see that it's not available from the Cognito payload sent to the Lambda event triggers. I'm also not sure of how to grab the refreshed token on the client if it refreshes after an hour of continued application use, without adding overhead to every change in the application.
Is there a way to request the current access token for a Cognito user from a server side process like a Lambda function if you're using Amplify on the client for the authentication flows? I cannot see anything in cognitoidentityprovider that allows me to retrieve the access token, but it's clearly needed to use GlobalSignOut.
You could use the Authorisation Code Flow with PKCE instead so the client is only exposed to the code which is then exchanged server-side using the token endpoint for cognito user pool / id token, access token and refresh token. You can return the user pool token to the client as that will expire after an hour while keeping the refresh token in your session manager on the server-side allowing you to fetch fresh tokens as needed or invalidate the session based on your requirements.
https://docs.aws.amazon.com/cognito/latest/developerguide/token-endpoint.html
I've found a workable solution that does not involve fetching the Access Token server side. We use AppSync for GraphQL - the access token is passed with each GraphQL request as an authorization header, and it can be accessed in the request template as follows:
#set( $myMap = {
"field": "${field}",
"user_id": $context.identity.sub,
"source_ip": $context.identity.sourceIp,
"arguments": $context.arguments,
"access_token": $context.request.headers.authorization
} )
{
"version" : "2017-02-28",
"operation": "Invoke",
"payload": $util.toJson($myMap)
}
In each Lambda resolver, I simply cache the access token when encountered, so that I always have the latest access token for the current user. My scheduled session manager function then retrieves the access tokens from the cache for any users it detects with an abandoned session and can use it as an input to GlobalSignOut.

AWS Amplify "Refresh Token has expired" after less than configured time (30 days)

I'm using React Native and Expo. Also using aws-amplify to manage users with Cognito's user pool.
Every so often my users are getting kicked out of the system because of "Refresh Token has expired" error. Those users were in the system in the previous week so their refresh token should still be valid. Any ideas?
I'm using:
aws-amplify 2.2.0
aws-amplify-react-native 2.2.3
react-native 0.59
expo 35
I think this is a misunderstanding of the docs. I was under the impression that the refresh token is being re-issued on every session, thus users should never get to the expiration time while they are active.
Apparently this is not the case, as users are issued a refresh token upon login only and that token is being persistent on the client side storage. No matter if they are active or not, this token is expired after 30 days (or else configured) and then need to re-login again.
(of course I'm aware that this is not an Amplify implementation)

Expire server side access token in short period

recently we encountered some strange behavior of server side access token. It expires in very short period (about 15 min). Scenario is following: User login to our page via facebook (server side) and we store access token. Some actions on our page can trigger post /feed. After few feed posts we suddenly started to getting error 400 and error 401.
Error 400 is probably due to limit of number of posts, but after error 401 access token becomes expired.
Every action respond with:
{
"error": {
"message": "Error validating access token: Session has expired at unix
time 1346321603. The current unix time is 1346320983.",
"type": "OAuthException",
"code": 190
"error_subcode": 463
}
Its hard to reproduce this behavior but we reproduced it couple of times on test environment (so we know when access token is created, that user didn't deauthorize app, nor change password).
Any ideas why access token becomes expired?
I double check that "Remove offline_access permission" was enabled on application advanced settings so i can get 60 days server side token.
Not sure why, but all access token have expire "in about hour" reported from access token debugger.
I created new application (also with "Remove offline_access permission") and now i got tokens which expires in 2 months.
Not sure why, but answer was to create new application.
By default facebook assigns a short lived access token. You need to request for long lived token.
Read the doc for how to get it : http://developers.facebook.com/roadmap/offline-access-removal/#extend_token
EDIT:
Previous link doesn't work anymore, use following link
https://developers.facebook.com/docs/roadmap/completed-changes/offline-access-removal/