FlowExchangeError('invalid grant') while authorising token - python

I am having a problem while using the access token retrieved using the refresh token. I am using python api client for Google doc. I have offline access mode and stored my refresh token in database in the userconsent part. Now using the refresh token, I am also able to retrieve the access token using requests.post. Now when I feed the access token thus retrieved to authenticate in the Flowexchange
self.flow = OAuth2WebServerFlow(CLIENT_ID, CLIENT_SECRET .... )
self.flow.step2_exchange(accesstoken)
I am getting FlowExchangeError(u'invalid_grant',). Anything I m missing ?
Thanks

Related

Python Uber SDK does not update access token after 30 days based on refresh token

I've created a script for Uber and it worked fine until my access token expired.
So here's this piece of code (almost similar to Uber SDK https://github.com/uber/rides-python-sdk):
session = Session(oauth2credential=OAuth2Credential(
client_id=credential_dict.get('client_id'),
access_token=credential_dict.get('access_token'),
expires_in_seconds=credential_dict.get('expires_in_seconds'),
scopes=credential_dict.get('scopes'),
grant_type=credential_dict.get('grant_type'),
redirect_url=credential_dict.get('redirect_url'),
client_secret=credential_dict.get('client_secret'),
refresh_token=credential_dict.get('refresh_token')))
client = UberRidesClient(session)
With the expired token I can not do anything further, it returns
uber_rides.errors.ClientError: 401: No authentication provided.
Also, I'm confused by "The SDK will handle the token refresh for you automatically when it makes API requests with an UberRidesClient."
How can I get my new access token using refresh token? I can authorize again and it works but is annoying.
You can get new access token if you have valid refresh token by using the token endpoint: https://login.uber.com/oauth/v2/token. For more information check the Uber documentation.
"When the user’s access_token has expired, obtain a new access_token by exchanging the refresh_token that is associated with the access_token using the Token endpoint".

How do I refresh an access token from Azure AD using django-rest-framework-social-oauth2?

The documentation gives an example of how to convert an Azure access_token that the user already has from the login process, but I'm not seeing anything about how to refresh that token. I managed to roll my own using adal, the Azure AD library for python, but I'm wondering if there's a better way using the tools included in DRF social oauth 2 or other django oauth packages that I'm just not finding. Please advise. Below is the function that refreshes my Azure AD token.
def refresh_social_access_token(self, request):
"""
This function leverages adal
https://github.com/AzureAD/azure-activedirectory-library-for-python
to refresh an expired access token.
.acquire_token_with_refresh_token(self, refresh_token, azure_ad_app_key,
resource, azure_ad_app_secret)
"""
user_social_auth = request.user.social_auth.filter(user=request.user) \
.values('provider', 'extra_data')[0]
context = AuthenticationContext(f'https://login.microsoftonline.com/{self.TENANT_ID}')
token = context.acquire_token_with_refresh_token(
user_social_auth['extra_data']['refresh_token'],
SOCIAL_AUTH_AZUREAD_OAUTH2_KEY,
user_social_auth['extra_data']['resource'],
client_secret=SOCIAL_AUTH_AZUREAD_OAUTH2_SECRET
)
try:
expiry = convert_iso_to_epoch(token["expiresOn"])
user_social_auth = request.user.social_auth.get(user=request.user)
user_social_auth.extra_data['expires_on'] = expiry
user_social_auth.save()
except KeyError:
HttpError('Oauth2 token could not be refreshed as configured.')

YouTube API without user OAuth process

I am trying to fetch captions from YouTube video using YouTube Data API (v3)
https://developers.google.com/youtube/v3/guides/implementation/captions
So, first I tried to retrieve a captions list using this url:
https://www.googleapis.com/youtube/v3/captions?part=snippet&videoId=KK9bwTlAvgo&key={My API KEY}
I could retrieve the caption id that I'd like to download (jEDP-pmNCIqoB8QGlXWQf4Rh3faalD_l) from the above link.
Then, I followed this instruction to download the caption:
https://developers.google.com/youtube/v3/docs/captions/download
However, even though I input the caption id and my api key correctly, it shows "Login Required" error.
I suppose I need OAuth authentication, but what I am trying to do is not related to my users's account, but simply downloading public caption data automatically.
My question is: Is there any way to process OAuth authentication just once to get an access token of my own YouTube account and then reuse it whenever I need it in my application?
I can't speak to the permissions needed for the captions API in particular, but in general, yes, you can OAuth to your app once using your own account and use the access and refresh tokens to make subsequent OAuth'd requests to the API. You can find the details of generating tokens here:
https://developers.google.com/youtube/v3/guides/auth/server-side-web-apps#Obtaining_Access_Tokens
To perform the steps manually (fortunately, you only need to do this once):
If access has already been granted for an app, it needs to be removed so that new auth credentials can be established. Go to https://security.google.com/settings/security/permissions (while logged into your account) and remove access to the app. If the client ID or secret change (or you need to create one), find them at https://console.developers.google.com under API Manager.
To grant access and receive a temporary code, enter this URL in a browser:
https://accounts.google.com/o/oauth2/auth?
client_id=<client_id>&
redirect_uri=http://www.google.com&
scope=https://www.googleapis.com/auth/youtube.force-ssl&
response_type=code&
access_type=offline&
approval_prompt=force
Follow the prompt to grant access to the app.
This will redirect to google.com with a code parameter (e.g.,
https://www.google.com/?code=4/ux5gNj-_mIu4DOD_gNZdjX9EtOFf&gws_rd=ssl#). Save the code.
Send a POST request (e.g., via Postman Chrome plugin) to https://accounts.google.com/o/oauth2/token with the following in the request body:
code=<code>&
client_id=<client_id>&
client_secret=<client_secret>&
redirect_uri=http://www.google.com&
grant_type=authorization_code
The response will contain both an access token and refresh token. Save both, but particularly the refresh token (because the access token will expire in 1 hour).
You can then use the access token to send an OAuth'd request manually, following one of the options here, essentially:
curl -H "Authorization: Bearer ACCESS_TOKEN" https://www.googleapis.com/youtube/v3/captions/<id>
or
curl https://www.googleapis.com/youtube/v3/captions/<id>?access_token=ACCESS_TOKEN
(When I tried the second option for captions, however, I got the message: "The OAuth token was received in the query string, which this API forbids for response formats other than JSON or XML. If possible, try sending the OAuth token in the Authorization header instead.")
You can also use the refresh token in your code to create the credential needed when building your YouTube object. In Java, this looks like the following:
String clientId = <your client ID>
String clientSecret = <your client secret>
String refreshToken = <refresh token>
HttpTransport transport = new NetHttpTransport();
JsonFactory jsonFactory = new JacksonFactory();
GoogleCredential credential = new GoogleCredential.Builder()
.setTransport(transport)
.setJsonFactory(jsonFactory)
.setClientSecrets(clientId, clientSecret)
.build()
.setRefreshToken(refreshToken);
try {
credential.refreshToken();
} catch (IOException e) {
e.printStackTrace();
}
youtube = new YouTube.Builder(transport, jsonFactory, credential).build();
I imagine you can do something similar in Python with the API Client Libraries, although I haven't tried Python.

Refresh Access Token Python-Fitbit (Orcasgit)

I can't figure out how to refresh my access token using this: https://github.com/orcasgit/python-fitbit
I've been able to get my Access Token, and Refresh Token. I've also been able to pull data from fitbit. But after my Access Token Expires I'm lost. I think I'm supposed to create a FitbitOauth2Client object, and use the refresh_token function to get a new token. Below is the closest I've gotten.
tokenfresh=fitbit.FitbitOauth2Client(client_id=ci,client_secret=consumer_secret,access_token=at,refresh_token=rt)
I've scoured all over for an answer so any help would be much appreciated.
The problem is not your code, FitBit provides a new refresh token when you use an older refresh token to generate an access token. You should keep track of this refresh token in order make you code work.
eg.
def fitbit_data(credentials):
client_id = os.environ.get("FITBIT_CLIENT_ID")
client_secret = os.environ.get("FITBIT_CLIENT_SECRET")
oauth = fitbit.FitbitOauth2Client(client_id=client_id,
client_secret=client_secret,
refresh_token=str(credentials.get('refresh_token')),
access_token=str(credentials.get('access_token')))
token = oauth.refresh_token()
update_refresh_token(token)
app_client = fitbit.Fitbit(client_id=client_id, client_secret=client_secret,
access_token=token.access_token, refresh_token=token.refresh_token)
steps = app_client.time_series(
resource='activities/steps',
period='1d'
)
return steps

Authentication with the Google Docs List API, Python and OAuth 2

I'm trying to use the Google Docs API with Python+Django and OAuth 2. I've got the OAuth access token, etc. via google-api-python-client, with the code essentially copied from http://code.google.com/p/google-api-python-client/source/browse/samples/django_sample/plus/views.py
Now, I assume I should be using the google gdata API, v 2.0.17. If so, I'm unable to find exactly how to authorize queries made using the gdata client. The docs at http://packages.python.org/gdata/docs/auth.html#upgrading-to-an-access-token (which appear outdated anyway), say to set the auth_token attribute on the client to an instance of gdata.oauth.OAuthToken. If that's the case, what parameters should I pass to OAuthToken?
In short, I'm looking for a brief example on how to authorize queries made using the gdata API, given an OAuth access token.
The OAuth 2.0 sequence is something like the following (given suitably defined application constants for your registered app).
Generate the request token.
token = gdata.gauth.OAuth2Token(client_id=CLIENT_ID,
client_secret=CLIENT_SECRET,
scope=" ".join(SCOPES),
user_agent=USER_AGENT)
Authorise the request token. For a simple command-line app, you can do something like:
print 'Visit the following URL in your browser to authorise this app:'
print str(token.generate_authorize_url(redirect_url=REDIRECT_URI))
print 'After agreeing to authorise the app, copy the verification code from the browser.'
access_code = raw_input('Please enter the verification code: ')
Get the access token.
token.get_access_token(access_code)
Create a gdata client.
client = gdata.docs.client.DocsClient(source=APP_NAME)
Authorize the client.
client = token.authorize(client)
You can save the access token for later use (and so avoid having to do the manual auth step until the token expires again) by doing:
f = open(tokenfile, 'w')
blob = gdata.gauth.token_to_blob(token)
f.write(blob)
f.close()
The next time you start, you can reuse the saved token by doing:
f = open(tokenfile, 'r')
blob = f.read()
f.close()
if blob:
token = gdata.gauth.token_from_blob(blob)
Then, the only change to the authentication sequence is that you pass this token to OAuth2Token by specifying a refresh_token argument:
token = gdata.gauth.OAuth2Token(client_id=CLIENT_ID,
client_secret=CLIENT_SECRET,
scope=" ".join(SCOPES),
user_agent=USER_AGENT,
refresh_token=token.refresh_token)
Hope this helps. It took a while to work it out :-).
This is from https://developers.google.com/gdata/docs/auth/overview:
Warning: Most newer Google APIs are not Google Data APIs. The Google Data APIs documentation applies only to the older APIs that are listed in the Google Data APIs directory. For information about a specific new API, see that API's documentation. For information about authorizing requests with a newer API, see Google Accounts Authentication and Authorization.
You should either use OAuth for both authorization and access or OAuth 2.0 for both.
For OAuth 2.0 API are now at https://developers.google.com/gdata/docs/directory.

Categories

Resources