Python: Facebook API showing invalid token

2020-06-29 10:10发布

问题:

I am using facepy facebook graph API to access my mailbox/messages and I followed the following two approaches:

1st Approach:

I used the access token I got from Graph Explorer facebook page and use the below code:

from facepy import GraphAPI
graph = GraphAPI(token)
print graph.get('/me')
#Rest of the code

The above code worked fine and I was able to retrieve all my messages using an FQL Query. The problem arised when my auth_token expired after sometime.

So, after some googling I shifted to approach two:

Now, what I did was created a facebook app gave it read_mailbox permission and got it's id and key and then used get_application_access_token method of facepy to get the token.

After retrieving the token I used:

token = facepy.utils.get_application_access_token(app_id, key)
graph.get('/me')
## OUT: OAuthError: [2500] An active access token must be used to query information about the current user.
facepy.utils.get_extended_access_token(token, app_id, key)
# OUT: OAuthError: [1] No user access token specified

Now, you can see the error(commented #) generated on using the application token.

I believe the error I am getting is because facebook needs the user_token and I am supplying it with app_token.

So, is it possible to access user data using the app_token and if not how can one issue a extended token which can access user data.

Update:

So, I followed @Johannes suggestion and tried this but ran into error:

from facepy.utils import get_extended_access_token
from facepy import GraphAPI
token = "My user access token got from https://developers.facebook.com/tools/explorer"
long_lived_access_token = get_extended_access_token(token)
graph = GraphAPI(long_lived_access_token)
graph.get('/me')

Now, when I ran the above code I got

TypeError: get_extended_access_token() takes exactly 3 arguments (1 given)

So, I changed it to long_lived_access_token = get_extended_access_token(token, None, None) and got

facepy.exceptions.OAuthError

So, I again I changed it to long_lived_access_token = get_extended_access_token(token, app_id, key) and I got the same exception/error as above.

So, is this a bug or am I doing something wrong.

PS: I installed the latest version from git.

回答1:

You're right in your assumption that you cannot use application access tokens to read a user's mailbox, but the error you're getting stems from the fact that you haven't initialized graph with an access token at all.

Be that as it may, you're on the right track in asking for how you can extend the user's access token. As you have already discovered, Facepy HEAD (soon to be version 0.9) has a function get_extended_access_token which accepts an existing short-lived user access token and extends it. Extended user access tokens last for 2 months, and you can read more about them in Facebook's documentation on the removal of offline_access permission.

If you want to use get_extended_access_token right now, you will have to install facepy from git:

$ pip install git+git://github.com/jgorset/facepy.git@b5153f460f2f52cef9a5e49a3b48b3fb8742356c

Once you've installed the right version of Facepy, you can extend an existing short-lived user access token and initialize a new instance of GraphAPI with it:

from facepy.utils import get_extended_access_token
from facepy import GraphAPI

long_lived_access_token, expires_at = get_extended_access_token(short_lived_access_token, application_id, application_secret_key)

graph = GraphAPI(long_lived_access_token)
graph.get('/me')


回答2:

There is nothing wrong with the API you are just not interpreting the result in a right way. If you try to print the result of long_lived_access_token = get_extended_access_token(token) it will not directly give you a long_lived_access_token instead it will provide you a tuple with contents:

long_lived_access_token = ('your token', datetime_object).

You can verify this by looking at the source code of utils.py. If you look at get_extended_access_token method it returns token, expires_at.

According to the facebook docs to get the extended access token one has to make request at the below endpoint

https://graph.facebook.com/oauth/access_token?             
    client_id=APP_ID&
    client_secret=APP_SECRET&
    grant_type=fb_exchange_token&
    fb_exchange_token=EXISTING_ACCESS_TOKEN 

and the response is something like token=mytoken&expire=5184000 where 5184000 means 60 days.

So, your final code will look something like:

from facepy.utils import get_extended_access_token
from facepy import GraphAPI

app_id = 'id'
key = 'key'

short_lived_access_token = 'short_token'
long_token = get_extended_access_token(short_token, id, key)

graph = GraphAPI(long_token[0])
print graph.get('/me')