I have the following test program:
from rauth.service import OAuth1Service, OAuth2Service
SUPPORTED_SERVICES = {
'twitter' : ( 'OAuth1', 'twitter', 'https://api.twitter.com/oauth', 'request_token', 'access_token', 'authorize', 'https://api.twitter.com/1/', None),
'facebook' : ( 'OAuth2', 'facebook', 'https://graph.facebook.com/oauth', None, 'access_token', 'authorize', 'https://graph.facebook.com/', 'https://www.facebook.com/connect/login_success.html'),
'google' : ( 'OAuth2', 'google', 'https://accounts.google.com/o/oauth2', None, 'token', 'auth', None, 'http://localhost'),
}
CLIENT_DATA = {
'twitter' : ('dummy_client_id', 'dummy_client_secret'),
'facebook' : ('dummy_client_id', 'dummy_client_secret'),
'google' : ('dummy_client_id', 'dummy_client_secret'),
}
USER_TOKENS = {
'user1' : {
'twitter' : ('dummy_access_token', 'dummy_access_token_secret'),
'facebook' : ('dummy_access_token', None),
'google' : ('dummy_access_token', None),
}
}
def test_google(user_id):
service_id = 'google'
oauthver, name, oauth_base_url, request_token_url, access_token_url, authorize_url, base_url, redirect_uri = SUPPORTED_SERVICES[service_id]
request_token_url = oauth_base_url + '/' + (request_token_url or '')
access_token_url = oauth_base_url + '/' + access_token_url
authorize_url = oauth_base_url + '/' + authorize_url
client_id, client_secret = CLIENT_DATA[service_id]
google = OAuth2Service(
client_id=client_id,
client_secret=client_secret,
name=name,
authorize_url=authorize_url,
access_token_url=access_token_url,
base_url=base_url)
access_token, access_token_secret = USER_TOKENS[user_id][service_id] # access_token_secret only needed for twitter (OAuth1)
session = google.get_session(access_token)
user = session.get('https://www.googleapis.com/oauth2/v1/userinfo').json()
print user
test_google('user1')
I have authorized my application to access the google account of user1
, and obtained an access_token. That access token has already expired, and the output of my program is:
{u'error': {u'code': 401, u'message': u'Invalid Credentials', u'errors': [{u'locationType': u'header', u'domain': u'global', u'message': u'Invalid Credentials', u'reason': u'authError', u'location': u'Authorization'}]}}
I would like to check whether the access token has expired when creating the session, not when requesting data. Is this possible? How can I verify if a session object is really authorized?
For clarification, what I am trying to do is the following:
I am currently having trouble with step 3. I can of course detect the 401 in the json reply to my GET, but it looks rather cumbersome to be forced to verify all GET accesses. What I am trying to do is to verify that the session is really active when I create it, and then assume for the whole duration of the session object, that it will stay active. Usually this will be just several milliseconds, while my webapp is processing the request and accessing the google API using the OAuth session object.
You have to call get_authorization_url
first, which user must open and grant you permissions to access his account, in return you will get a code from redirect_uri
callback's query params, which you can exchange for access_token
:
params = {
'scope': 'email',
'response_type': 'code',
'redirect_uri': redirect_uri,
'access_type': 'offline', # to get refresh_token
}
print google.get_authorize_url(**params)
According to documentation this code should work:
data = {
'code': 'code you got from callback',
'grant_type': 'authorization_code',
'redirect_uri': 'http://localhost/oauth2',
}
response = google.get_raw_access_token(data=data)
In response you will get a JSON data like this:
{
"access_token" : "ya29.AHE<....>n3w",
"token_type" : "Bearer",
"expires_in" : 3600,
"id_token" : "eyJh<...>QwNRzc",
"refresh_token" : "1/X86S<...>Vg4"
}
As you can see there is expires_in
(seconds), you have to store the time when you got the token and compare at later with current time + expires_in
.
If the token expired, you can refresh it with refresh_token
later without asking for user confirmation again:
response = google.get_raw_access_token(data={
'refresh_token': refresh_token,
'grant_type': 'refresh_token',
})
print response.content
Notice, that refresh_token
will only be returned the first time user authorises the app.
See this question for details.
Alas it seems that you can't use get_auth_session
, because internally it only extracts access_token
and everything else is discarded.
If you get access_token
immediately without getting auth code
first, you still get expires_in
in callback. From the docs: