Can't authorize with google plus API - python

I am trying to authorize my app using google plus. However, everything I've tried always gives me a 404 when I use the people service and attempt to get 'me', except when I log in with the user who created the Google+ API app. It doesn't make any sense to my why that would be the case.
from httplib2 import Http
from apiclient.discovery import build
credential = gp_client.step2_exchange(request.REQUEST)
http = Http()
http = credential.authorize(http)
service = build("plus", "v1", http=http)
o = service.people().get(userId='me').execute()
The same is also true when I use the Google+ explorer:
http://code.google.com/apis/explorer/#_s=plus&_v=v1&_m=people.get&fields=emails
If I switch to private with the user who created the API, then I can fetch 'me', but if I authorize another user, then I can't fetch 'me'.
Any ideas what is happening?

Finally figured out what this was. Google lets you authorize any google account for an app. However, if the authorizing user hasn't upgraded to Google+, when the app makes its first Google+ API request, the request will 404. This is mind boggling, because when I setup the OAuth2WebServerFlow I specified "plus.me" as the scope... IMHO Google should tell the user to upgrade to Google+ when they try to authorize this OAuth request.
gp_client = OAuth2WebServerFlow(
settings.GOOGLE_PLUS_CONSUMER_ID,
settings.GOOGLE_PLUS_CONSUMER_SECRET,
scope='https://www.googleapis.com/auth/plus.me',
)

Related

Use Google API with a token [Django & AllAuth]

I am using AllAuth on my Django app to manage user authentication. With that my users can connect their Google accounts and i get a google API token (with appropriate scopes).
I would like to use that token to access google APIs (Calendar v3 in my case) with that token, as my user already used OAuth2 to sign-in on my website, and gave me access to the calendar API.
Google only gives the full process on their website (from auth to api), is there a way to build my idea, or is it simply impossible?
i have tries drive = build('calendar', 'v3', credentials=credentials) as said here but "credentials" needs to be part of an oauth2client and not just a simple string token.
Thank you for your precious time.
Simon
I know its an older question but I finally found something that worked for me. After a successful authentication with allauth, I did this to get the client token and then build the service.
from googleapiclient.discovery import build
from google.oauth2.credentials import Credentials
from allauth.socialaccount.models import SocialToken, SocialApp
...
# request is the HttpRequest object
token = SocialToken.objects.get(account__user=request.user, account__provider='google')
credentials = Credentials(
token=token.token,
refresh_token=token.token_secret,
token_uri='https://oauth2.googleapis.com/token',
client_id='client-id', # replace with yours
client_secret='client-secret') # replace with yours
service = build('calendar', 'v3', credentials=credentials)

Python Flask-OAuth validate a token for a webapi

I went through the Flask OAuth api, and its pretty clear how to do authentication for a web app. The web app gets redirected to the authentication provider login page, where access is granted, and returns back to the web app with a token.
However, for web api scenarios, where a client is pre authorized to call the web api, the request will have a Bearer token along with the call. Is there any example on how to validate this token? I see apis like validate_access_token() in the OAuth2 library, but I cant see any examples where people use it for web apis.
I use Azure AD for authentication, and have created an AAD application, and am able to get a token from it through the adal package on the client side (with the clientId and clientKey from AAD). But I havent been able to authorize it yet on the web api side, because it seems most scenarios look at web app authentication and not web api scenarios. Any ideas on how to authenticate on server side?

Google Cloud Endpoints: Authentication issues (error 403)

I'm trying to connect to my Google Cloud Endpoints API that is running as an Appengine app:
#endpoints.api(name='helloworldendpoints', allowed_client_ids=["1234", "12345"], version='v1', auth_level=endpoints.AUTH_LEVEL.REQUIRED)
class HelloWorldApi(remote.Service):
...
The API request is as follows:
scopes = ["https://www.googleapis.com/auth/userinfo.email"]
credentials = ServiceAccountCredentials.from_json_keyfile_name("CloudEndpointsClient.json", scopes)
from httplib2 import Http
http_auth = credentials.authorize(Http())
from apiclient.discovery import build
api_root = 'https://myapp.appspot.com/_ah/api'
api = 'helloworldendpoints'
version = 'v1'
discovery_url = '%s/discovery/v1/apis/%s/%s/rest' % (api_root, api, version)
service = build(api, version, discoveryServiceUrl=discovery_url)
response = service.myFunction(myparameter = "123456").execute(http=http_auth)#
print response
The requests work well if I remove authentication requirements.
I know that authentication works since the error changes if after authenticating.
The error message I'm getting is:
googleapiclient.errors.HttpError: https://my-app.appspot.com/_ah/api/helloworldendpoints/v1/obtainScoreFromEmail?myparameter=1234&alt=json returned "Access Not Configured. has not been used in project 123456789 before or it is disabled. Enable it by visiting https://console.developers.google.com/apis/api/helloworldendpoints/overview?project=123456789 then retry. If you enabled this API recently, wait a few minutes for the action to propagate to our systems and retry.">
I cannot enable the API in my Google Cloud Project, since the API does not exist.
What I found to work is a hack around. I used a user authentication (instead of server) on the same project for the same API which worked (https://cloud.google.com/endpoints/docs/frameworks/python/access_from_python).
After I switched back to my initial server auth. method it started working.

Google OAuth 2.0 exchanging code form access token takes forver

I have a basic web app that I uses Google OAUTH flow. The web app navigates to /oauth which triggers the oauth flow. the authorization server then redirects the client to /oauth2callback. I am trying it out locally and the first step works fine. The server is able to redirect the client to google's authorization server and receive the code that is meant to be exchanged for an access token. However, when I try to exchange the code using flow.step2_exchange the http requests hangs for a very long time. Usually the request times out. Occasionally I do get a response back with a valid access token, which leads me to believe that the logic is (generally speaking) sound.
Does anybody know what might be causing google to delay the response for 30 seconds or more? Could it be that google is throttling development requests? Has anyone encountered something like this before? Is there something I am doing wrong? I should note that I am currently using google own oauth2 library but I've tried constructing the http requests manually and that didn't help either. It still hangs on https://accounts.google.com/o/oauth2/token.
This is the flask code for the oauth flow:
from oauth2client.client import OAuth2WebServerFlow
#app.route('/oauth', methods=['GET'])
def oauth():
print "oauth called: "
flow = OAuth2WebServerFlow(
client_id=config.GOOGLE_OAUTH_CLIENT_ID,
client_secret=config.GOOGLE_OAUTH_CLIENT_SECRET,
scope='https://www.googleapis.com/auth/userinfo.email',
redirect_uri='http://localhost:6060/oauth2callback')
auth_uri = flow.step1_get_authorize_url()
return redirect(auth_uri)
#app.route('/oauth2callback', methods=["GET"])
def oauth_callback():
code = request.args['code']
flow = OAuth2WebServerFlow(
client_id=config.GOOGLE_OAUTH_CLIENT_ID,
client_secret=config.GOOGLE_OAUTH_CLIENT_SECRET,
scope='https://www.googleapis.com/auth/userinfo.email',
redirect_uri='http://localhost:6060/oauth2callback')
credentials = flow.step2_exchange(code)

Google App Engine (Python), OAuth2, Service Accounts, User Delegation, Youtube Service

I'm using the Youtube Data API (v3), along with the Python client library on Google App Engine.
Here is a simple snippet of code that fails:
kwargs = {'prn' : google_oauth_user_email}
credentials = SignedJwtAssertionCredentials(google_oauth_email, google_oauth_key, scope=YOUTUBE_SCOPE, **kwargs)
http = credentials.authorize(httplib2.Http())
youtube = build(YOUTUBE_API_SERVICE_NAME, YOUTUBE_API_VERSION, http=http)
request = youtube.channels().list(part="snippet", id="25")
response = request.execute(http=http)
which results in:
Failed to retrieve access token: {
"error" : "access_denied"
}
If I remove the kwargs so as not to delegate user access, this request works fine. The Service Account is registered against the same user account to which delegation is being requested.
My ultimate goal is to upload videos (on behalf of that user) using the Server-to-Server two-legged OAuth2 flow.
Can anybody explain to me why delegation to the same user account as that which the Service Account is already registered fails, and how I might be able to allow it?

Categories