I am using facepy facebook api to fetch messages from my facebook account. I have got myself long live access token with validity of 60days using the API. Now, in my program before querying for message I want to check wether my token has expired or not and if expired fetch a new one.
I am using get_extended_access_token which also returns a datetime instance describing when token expires. Now I think it is not a effecient way to use get_extended_access_token because everytime I am going to query for new message it will also fetch the access token(I know it is same as before) but I think this is a overhead.
So, I googled and found that we can also use
https://graph.facebook.com/debug_token?input_token=INPUT_TOKEN&access_token=ACCESS_TOKEN
to debug the token
So I supplied my long live access token instead of INPUT_TOKEN and ACCESS_TOKEN and it gave me a json response:
{
"data": {
"app_id": XXXXX,
"is_valid": true,
"application": "YYYYY",
"user_id": ZZZZZZ,
"issued_at": 1349261684,
"expires_at": 1354445684,
"scopes": [
"read_mailbox"
]
}
}
Now if you look at expires_at field it is showing 1354445684 seconds and when I tried to convert it into days/months it gave me 15676 days and when I checked the same token in graph explorer using the debug option it showed
expires_at: 1354445684(about 2 months)
Now, what I don't understand is how 1354445684 is equivalent to 2 months and how to achieve this in python.
Also comment on which is the better approach to check wether token has expired or not API or using the facebook url?
Now if you look at expires_at field it is showing 1354445684 seconds and when I tried to convert it into days/months it gave me 15676 days
Then you’ve done (or understood) something wrong.
expires_at 1354445684 is a Unix Timestamp, and equals Sun, 02 Dec 2012 10:54:44 +0000 translated into a human-readable date.
And that is pretty much two month from the issued_at timestamp 1349261684, a.k.a. Wed, 03 Oct 2012 10:54:44 +0000
I recommend you rely on exceptions to verify whether the token was valid instead of making a separate request to guarantee it:
from facepy import GraphAPI
graph = GraphAPI(token)
try:
graph.get('me')
except GraphAPI.OAuthError:
# Redirect the user to renew his or her token
Related
I have a dashboard where users click a button and is redirected to Facebook where they allow me to access ad reports. It works. I get an access token and make another request to get the long access token which expires every 60 days.
I was mistakenly under the impression that as long as the access token was not expired e.g. 3 days prior to expiration, I would be able to extend for another 60 days. No such luck. I try and get a new long-lived access token the expiration is the same.
How do I get a token where my users do not have to reauth every 60 days? I cant find the docs.
This post claims to be able to get a permanent access token but I don't know how to modify it for a client.
import facebook
graph = facebook.GraphAPI(access_token=user_long_token, version="3.0")
pages_data = graph.get_object("/me/accounts")
permanent_page_token = pages_data["data"][0]["access_token"]
page_id = pages_data["data"][0]["id"]
DO I modify /me/accounts? If so how for a client? I can pass the user_long_token but the response I get is:
print(pages_data)
{'data': []}
I assume I have to replace /me/accounts with something else. All I have in an account id, an access token, and long access token.
Utterly confused. Thanks
Overview
Based on the concept found on Settings section of Long Running Refresh Token.
It means that you need to refresh [access token] every 5 mins and you need to replace your refresh token in 7 days after it has been issued.
This will enable user to maintain refresh token session as long as we can refresh it within 7 days (e.g. 'JWT_REFRESH_EXPIRATION_DELTA': timedelta(days=7)).
Note that you can't call refreshToken(refreshToken: $refreshToken) with an expired refresh token as this may result in "message": "Refresh token is expired".
Problem
Now the struggle here is how do we know that the refresh token will expire in 7 days? So we can create a logic to check if it has 1 day left for the session then trigger a refreshToken() mutation?
Conclusion
Without knowing the expiration date of a refresh token developers will have to integrate in storing the date after the refresh token has been issued in the client side to determine how old the refresh token is.
Well if I am missing something maybe there is already a simple approach how to handle the checking of refresh token expiration date?
A JWT token is actually a Base64 encoded string that stores a lot of its own properties, including the one you're looking for. The beauty of a JWT token is that is also includes a hash, which is based on the useful parts of the token. This means that if someone changes a JWT token by changing the expiration/issue date, the username, or a custom value, the hash will no longer be valid and the token will be rejected.
In your case this means that you can accept a token, decode the string into a JSON object, check its value, and base your response on its contents. Hope this helps!
I have an issue with access to Youtube Analytics API for random youtube channels.
After a successful authorization with following scopes:
https://www.googleapis.com/auth/youtube.readonly
https://www.googleapis.com/auth/yt-analytics.readonly
I'm saving the token and refresh token in the database. Everything works well for some time. After a while (eg. three months) when my app makes a request, Google returns 403:
{
"error": {
"errors": [
{
"domain": "global",
"reason": "forbidden",
"message": "Forbidden"
}
],
"code": 403,
"message": "Forbidden"
}
}
but only for Youtube Analytics API, other endpoints in Youtube Data API works fine with this token.
That happen for random accounts (channels). Owners of this channels didn't revoke access to my app, didn't change account password etc.
This issue affects about 40% of all channels in my application (the time when Youtube Analytics API stops working is different, from 1 to 6 months after obtaining OAuth2 token). Then I have to send them periodically a new authorization url.
Where is the problem?
This is how I generate an auth url and make requests:
Auth URL:
flow = client.flow_from_clientsecrets(
secret_file_path,
scope=["https://www.googleapis.com/auth/youtube.readonly",
"https://www.googleapis.com/auth/yt-analytics.readonly"],
redirect_uri=redirect_url,
prompt="consent"
)
flow.params["access_type"] = "offline"
url = flow.step1_get_authorize_url(state=state)
Stats request:
auth = client.OAuth2Credentials.from_json(credentials_from_db)
http_auth = auth.authorize(httplib2.Http())
api = discovery.build("youtubeAnalytics", "v1", http=http_auth,
cache_discovery=False)
api.reports().query(
ids="channel==%s" % channel_id,
metrics="estimatedMinutesWatched",
dimensions="video",
start_date=start_date,
end_date=end_date,
max_results=20,
filters="video=={}".format(",".join(video_ids))
).execute(http=http)
I'm using google-api-python-client 1.6.5
Edit
I attached screenshot while debugging requests to google API using google-api-python-client. Here's what's going on:
Retrieving channel's base stats using Youtube Data API
Retrieving channel's advanced stats using Youtube Analytics API
My point is that, the refresh token is successfully exchanged in both cases but works only with Youtube Data API. I purposely exchange it twice. The same result is when I access only Youtube Analytics API with one successful token exchange (without calling Youtube Data API).
And the most fun part is that, this code works for some time (a couple weeks or months) and then stops :-)
Ok lets start with a little background information.
There are sevral reasons why a refresh token would stop working.
It gets to old refresh tokens expire after six months if not used.
A user can reauthecate your application and get a new refresh token both refresh tokens will work you can have a max of fifty outstanding refresh tokens then the first will stop working.
the user can revoke your access.
Wakey daylight savings time bug of 2015. (we wont talk about that)
Now none of this is the case for you. Why because the refresh token still works your just drooping a scope. Which is crazy a user cant remove your access to one scope and it wont expire one scope.
That being said i am leading towards this being a bug. I have sent an email off to someone I know who is on the Oauth team.
In the mean time. I have an idea?
What happens if you try and request a new access token using the refresh token? Could it be an issue with the access token that was returned to you?
Given that you say that the token refresh works but the API call returns error, the only thing that I suspect is some issue on the api side.
Are you making these API calls from your server? For how many users? You may be running into per IP based limits. I don't know that for sure.
I think the easiest way to find the issue will be if you can send us a few tokens that start returning error. We can lookup if the tokens became invalid or there is an issue on the API side.
You can email them to oauth-help#google.com
I have set up a python script that can pull data from Gmail account, but I would like to set it up in a way that it would only pull new message since the last time I made the API call (I will be pinging the server regularly).
I have looked at Push notification and Pub/Sub, but I am not quite sure if these are relevant or I should be looking at something else. Gmail also has Users.history: list function, but I am wondering if this can be used in any useful way.
You could list messages as you usually do, but saying that you want messages after a certain timestamp. This way, you can poll for new messages e.g. every minute, giving the last time you checked for messages in seconds since the epoch:
Request
q = is:unread AND after:<time_since_epoch_in_seconds>
GET https://www.googleapis.com/gmail/v1/users/me/messages?q=is%3Aunread+AND+after%3A1446461721&access_token={YOUR_API_KEY}
Response
{
"messages": [
{
"id": "150c7d689ef7cdf7",
"threadId": "150c7d689ef7cdf7"
}
],
"resultSizeEstimate": 1
}
Then you just save the timestamp when you issued the request, and use this timestamp one minute later.
I'm using facepy for retrieving fb comments and posts (This is the objective). I've given a valid access token (generated from http://developers.facebook.com/tools/explorer/?method=GET&path=me)
The error generated is:
NameError: name 'AAACEdEose0cBAHshwZCGJ6dHPb0x68c.......D' is not defined. And/OR
facepy.exceptions.OAuthError: [190] Error validating access token: Session has expired at unix time 1359752400.
I believe I've generated the correct access token (with the correct permissions) I thought I would test the facepy library for retrieving photos first. Is their a faster way to retrieve comments, respective user ids, and time stamp from a public fan page (I am guessing most of my target pages have 'public information')
Can someone help me on this?
from facepy import GraphAPI
graph = GraphAPI(AAACEdEose0cBAHshwZCGJ6dHPb0x68c.......D)
graph.get('me/posts')
graph.post(
path = 'me/photos',
source = open('parrot.jpg')
Never tried with the FB but some of the solutions which worked with other API's.
Error validating access token: Session has expired at unix time 1359752400.
Says All. However mostly occurs when I did connected it to some DB for storing some information retrieved from the API.I am sure you have made a right key and password so don't worry about it. Make sure the other connection is still open.
Second, it happened again when I did not accessed the API for weeks so make sure to log in once or twice.
Your API needs to be in quotes...
also generate an extended token via the below