Good afternoon, I am making an API in which it will connect to the dropbox API, the problem stems from the fact that the token does not last long, which is unclear in the documentation, does anyone of you know how to obtain the token through the endpoint or That it does not expire, I would appreciate it.
I looked in the documentation and I don't understand it well and some video tutorials don't mention it.
Dropbox is in the process of switching to only issuing short-lived access tokens (and optional refresh tokens) instead of long-lived access tokens. You can find more information on this migration here.
Apps can still get long-term access by requesting "offline" access though, in which case the app receives a "refresh token" that can be used to retrieve new short-lived access tokens as needed, without further manual user intervention. You can find more information in the OAuth Guide and authorization documentation.
You can find examples of using the OAuth app authorization flow in the Dropbox Python SDK here
Related
I am trying to build an python application for my server to run 24 hours and overwrite a file in dropbox every minute. When I built this application it stopped working after an hours for new token. I can't awake 24 hour to add new token every token. I just want a way that help me in doing setup of this. With dropbox there is no option to remove short length expire from token. Please keep it simple to underatnd easily dropbox documentation is hard for me to understand.
I just want a solution for this problem. I tried refresh token but it also required user interaction so no use.
Using refresh tokens is the right solution here. Just like with Dropbox access tokens, manual user interaction is required initially to get a Dropbox refresh token, but once the app has a refresh token it can store and re-use it repeatedly without further manual user interaction.
For reference, Dropbox is in the process of switching to only issuing short-lived access tokens (and optional refresh tokens) instead of long-lived access tokens. You can find more information on this migration here.
Apps can still get long-term access by requesting "offline" access though, in which case the app receives a "refresh token" that can be used to retrieve new short-lived access tokens as needed, without further manual user intervention. You can find more information in the OAuth Guide and authorization documentation.
You can find examples of using the OAuth app authorization flow in the Dropbox Python SDK here.
I can successfully authenticate with the pattern outlined here:
https://developers.google.com/youtube/v3/docs/videos/list?apix=true
for a simple prototype in Google Colab. However I cannot for the life of me figure out how to authenticate in a Cloud Function as there is no user to complete the flow. I'm sure it's a standard pattern, however I'm more familiar with the GCP APIs and the googleapiclient is a new one for me.
I have set up service account credentials with the right access, but I'm not even sure whether it makes sense to use these in a Cloud Function (maybe stored on GCS), or whether there is (as I hope) a more elegant solution.
Any help would be hugely appreciated, thanks!
Not really familiar with Youtube Data API, however based on the API reference for some details you need to issue a call as a video owner (e.g. processingDetails). This means that you need to use three-legged OAuth2 flow. For that you can either:
Setup another function that will generate an authorization URL ->
present it to the user -> setup another function as redirect_uri to
obtain authorization code -> exchange it for access and refresh
tokens -> store refresh token someplace safe where original function
can fetch it.
Obtain refresh token outside of Cloud Functions and hardcode it.
Hardcoding credentials is generally not a good practice, hence a better option would be to have a service account make requests on behalf of a user, but this is only possible for GSuite users via domain-wide delegation. With this, after setup, you would use sub claim with the email address of the impersonated user. You can see more here (make sure to switch to HTTP/REST to understand how JWT is created or, if you're not interested in details, just select Python.
Im trying to access a google cloud endpoint from a cmdline using service account similar to
https://code.google.com/p/google-api-python-client/source/browse/samples/service_account/tasks.py
As instructed from the example, I created a clientid + pk12 cert and using them to create the credential with the SignedJwtAsertionCredential call from the oauth2client.client module.
Works as expected when I call my cloud endpoint running on my local devserver however when I call the deployed gae cloud endpoint I get
Oauth framework user didn't match oauth token user.
Seems to be failing on the oauth.get_client_id(scope) call from user_id_token._set_bearer_user_vars().
When I added a traceback on the exception, it looks to be coming from _maybe_raise_exception
E 2014-01-02 10:30:53.926 raise NotAllowedError(error_detail)
E 2014-01-02 10:30:53.926 NotAllowedError
Is there a way to resolve this error without changing the app's authentication type? Seems to be not allowing the request due to the domain restriction?
My goal is to call the cloud-endpoint without having a user involved, not sure if i'm the right path using the SignedJwtAsertionCredential call or if possible?
Additional info.
The authentication type of the endpoint is set to "Google App Domain"
The user_required is True on the endpoint method
The access token generated from the SignedJwtAssertCredential is as expected when i use
https://www.googleapis.com/oauth2/v1/tokeninfo?access_token=ya29.
The endpoint works as expected from the api explorer and when there is the auth flow involved.
Using the endpoints_proto_datastore library.
From extensive research I have come to the conclusion that implementing OAuth is not a viable authentication method for apps because of the simple fact that it is horrible to implement. After spending countless hours debugging and asking questions on Stackoverflow about a simple Twitter oAuth implementation, all while receiving countless wrong answers(which safely lets me deduce that a large percentage of developers don't know how to use OAuth) I decided to never again use OAUTH.
So I leave you with the words of the great French Emperor Napoleon Bonaparte
"Una retirada a tiempo es una victoria" -Napoleon Bonaparte
which basically means get out while your ahead and dont waste your time with OAUTH!
Additional information
while experiencing my frustrations with OAUTH I ended up doing some research on who actually came up with this headache inducing concept, and it turns out that the creator has quit this project and has actually publicly denounced OAUTH in his blog:
http://hueniverse.com/2012/07/oauth-2-0-and-the-road-to-hell/ interestingly titled the road the hell. So if the creator is not using OAUTH then you definitely shouldn't either. I have started a petition on https://petitions.whitehouse.gov/ to make the use of OAUTH illegal, so if you like you can join the fight and give us a vote, it is currently gaining traction and we appreciate any support, so go ahead and give it a vote.
The issue was due to the "Google Apps" Authentication Type selected for the application. This setting requires all accounts using the users api to be example.com accounts and the service account is obviously not one.
Once we changed the Auth Type to Google accounts, there was no issue with using service account and validating the client_id.
I have a simple scenario for which I can't find solution. I'd like to use Docs API for my application, but I want to use only one application account to store documents and perform all the API calls. So I don't want to use all this redirect_uri stuff, that needs any kind of user interaction - only my app and it's own Google account.
I've found similar question here: gdata-python-api + Analytics with simple auth but the solution still involves user interaction (yes, probably only once but I still don't like it as most of the interactions with API will be done by some daemon).
I'm using gdata-python-client for interactions with API. I'm not sure if I understand correctly if ServiceAccount authentication might be a solution, but couldn't find any examples of how to perform it via gdata-python-client lib (can somebody share working code?).
To access the documents owned by this single user, you must have an access token for that user. There's not really any way around this. The access token is how Google identifies your project, which user's data you'd like access to, and that you have all of the necessary permissions granted.
It sounds like you've already found the solution: You must go through the OAuth 2.0 dance at some point in time and store the refresh_token for subsequent access. Be aware, though, that refresh_tokens may not last forever. For example, if access is revoked, it will stop working. For this reason, it's wise to expose the ability to execute the OAuth 2.0 dance again from an administrative page in your application.
I'm working on converting a Python script using the Google gdata API client + user/pass authentication to something more suitable for production (an API key). I am pretty frustrated with the muddled state of their documentation on authentication. I admittedly don't have a great grasp of OAuth2, but it seems like it's way more complicated for my usage case, which is: Hit Google Analytics every 24 hours to get the X most popular articles on our site.
In this scenario, we're not dealing with modifying someone's personal data, and all activity is centered on one account. It doesn't seem like OAuth2 is worth the complexity for something so simple.
I see that on the Google API Console (https://code.google.com/apis/console/), I've registered there and notice that there's a "Simple API Access" section with one key beneath the "Client ID for web applications" (which appears to be OAuth2). There's also the Google domain update page, https://www.google.com/accounts/UpdateDomain, but that appears to be OAuth related.
Is there any way to use this Simple API Access key (not OAuth) for retrieving analytics data with the Python gdata client, and if so, does anyone have any authentication examples? I already have the data retrieval stuff working once authenticated, but I'm using the user/pass approach, which is not appropriate for production.
Greg,
If you are already using the library gdata-python-client, this is relatively easy to do if you are the only user that your application will be authorizing.
The general mechanisms were detailed in a blog post in September, 2011, but I'll describe them here for completeness.
Part 1: Go to the APIs console and start a new project.
Part 2: From the project, go to "Services" and enable "Analytics API"
Part 3: From the project, go to "API Access" and click "Create an OAuth 2.0 client ID..." (you'll need to provide a product name, though the value you provide won't matter). When asked for the application type, select "Installed Application" and then "Create client ID". Since you will be the only user, you will only need one refresh token, and you can get this by authorizing from a desktop application a single time.
Part 4: Get your client id and client secret from the APIs console and then create an empty token:
import gdata.gauth
CLIENT_ID = 'id-from-apis-console'
CLIENT_SECRET = 'secret-from-apis-console'
SCOPE = 'https://www.google.com/analytics/feeds/' # Default scope for analytics
token = gdata.gauth.OAuth2Token(
client_id=CLIENT_ID,
client_secret=CLIENT_SECRET,
scope=SCOPE,
user_agent='application-name-goes-here')
I got the scope from GData FAQ, though I'm not sure if it is correct.
Part 5: Use the token to create authorization URL for you to visit:
url = token.generate_authorize_url(redirect_uri='urn:ietf:wg:oauth:2.0:oob')
Since your application is an "Installed Application", your redirect URI is the default 'urn:ietf:wg:oauth:2.0:oob'. (Also note, the blog post had a typo and used the keyword argument redirect_url.)
Part 6: Visit the url and authorize your application to make requests on behalf of your account. After authorizing, you'll be redirected to a page with a code on it. This code will be used to exchange for an access token and a long-lived refresh token. The code has a life of 10 minutes and the access token has a life of an hour. The refresh token will allow you to get new access tokens for signing requests in perpetuity (or until you revoke the permission from your account).
Part 7: Use the code to get an access token:
code = 'random-string-from-redirected-page'
token.get_access_token(code) # This returns the token, but also changes the state
This again differs slightly from the blog post, because we are using an installed application.
Part 8: With the token you can now make all requests you want to make to the analytics client:
import gdata.analytics.client
client = gdata.analytics.client.AnalyticsClient()
token.authorize(client)
This is the big money right here. When an access token expires, the API requests signed with that token are rejected. However, by authorizing the client as above, when the said requests fail, the token attempts to use the refresh token to obtain a new access token. If it successfully obtains a new access token, the client resends the original API request, signed with the new access token.
I don't know anything about the Analytics API so I won't provide any more details there.
Future Use Note 1: Saving information for future use. You can re-use this from different places and after this use very easily. There are methods called token_to_blob and token_from_blob provided by the library that allow turning a token into a string and converting out of a string:
saved_blob_string = gdata.gauth.token_to_blob(token)
Once you have done this, you can store the string in a file and kill your running Python process. When you'd like to use it again:
saved_blob_string = retrieve_string_from_file() # You'll need to implement this
token = gdata.gauth.token_from_blob(saved_blob_string)
Future Use Note 2: This token will be able to be used to authorize a client and perform all your magic again and again, so long as you have the refresh token around. If for some reason you would like to get an access token again without calling token.generate_authorize_url, you'll need to manually set this on the object:
token.redirect_uri = 'urn:ietf:wg:oauth:2.0:oob'
Future Use Note 3: Also, if you lose your refresh token and would like to get another one without having to go to the browser to revoke the original, you can use the approval_prompt parameter to get a new refresh token by visiting the url generated by:
url = token.generate_authorize_url(
redirect_uri='urn:ietf:wg:oauth:2.0:oob',
approval_prompt='force')