Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

User info using OAuth with Google App Engine

When using OAuth 2.0 and Python I want to have the user id or email to store/retrieve the OAuth access token as I want to modify a calendar even after the user has gone away.

There is so much documentation and half of it is deprecated (OAuth 1.0) that I've not been able to figure this out.

I have the following code:

import webapp2
import os

from apiclient.discovery import build
from oauth2client.appengine import OAuth2DecoratorFromClientSecrets
from google.appengine.api import oauth

user_scope = 'https://www.googleapis.com/auth/userinfo.profile'

decorator = OAuth2DecoratorFromClientSecrets(
    os.path.join(os.path.dirname(__file__), 'client_secrets.json'),
    scope=('https://www.googleapis.com/auth/calendar', user_scope)
)

service = build('calendar', 'v3')

class MainHandler(webapp2.RequestHandler):
    @decorator.oauth_required
    def get(self):
        self.response.write('Hello world!')

        user = oauth.get_current_user(user_scope)
        if user:
            self.response.write('%s\n' % user)
            self.response.write('- email    = %s\n' % user.email())
            self.response.write('- nickname = %s\n' % user.nickname())
            self.response.write('- user_id  = %s\n' % user.user_id())
        else:
            self.response.write('No user found...')


app = webapp2.WSGIApplication([
    ('/', MainHandler),
    (decorator.callback_path, decorator.callback_handler())
], debug=True)

This works locally in the test environment, however when I deploy it and run it online I get the following error:

Traceback (most recent call last):
  File "/base/data/home/runtimes/python27/python27_lib/versions/third_party/webapp2-2.5.2/webapp2.py", line 1535, in __call__
    rv = self.handle_exception(request, response, e)
  File "/base/data/home/runtimes/python27/python27_lib/versions/third_party/webapp2-2.5.2/webapp2.py", line 1529, in __call__
    rv = self.router.dispatch(request, response)
  File "/base/data/home/runtimes/python27/python27_lib/versions/third_party/webapp2-2.5.2/webapp2.py", line 1278, in default_dispatcher
    return route.handler_adapter(request, response)
  File "/base/data/home/runtimes/python27/python27_lib/versions/third_party/webapp2-2.5.2/webapp2.py", line 1102, in __call__
    return handler.dispatch()
  File "/base/data/home/runtimes/python27/python27_lib/versions/third_party/webapp2-2.5.2/webapp2.py", line 572, in dispatch
    return self.handle_exception(e, self.app.debug)
  File "/base/data/home/runtimes/python27/python27_lib/versions/third_party/webapp2-2.5.2/webapp2.py", line 570, in dispatch
    return method(*args, **kwargs)
  File "/base/data/home/apps/s~myapp/oauth2client/appengine.py", line 714, in check_oauth
    resp = method(request_handler, *args, **kwargs)
  File "/base/data/home/apps/s~myapp/main.py", line 29, in get
    user = oauth.get_current_user('https://www.googleapis.com/auth/userinfo.profile')
  File "/base/data/home/runtimes/python27/python27_lib/versions/1/google/appengine/api/oauth/oauth_api.py", line 100, in get_current_user
    _maybe_call_get_oauth_user(_scope)
  File "/base/data/home/runtimes/python27/python27_lib/versions/1/google/appengine/api/oauth/oauth_api.py", line 231, in _maybe_call_get_oauth_user
    _maybe_raise_exception()
  File "/base/data/home/runtimes/python27/python27_lib/versions/1/google/appengine/api/oauth/oauth_api.py", line 246, in _maybe_raise_exception
    raise NotAllowedError(error_detail)
NotAllowedError

What am I missing that causes this error?

like image 222
Piet Paulus Avatar asked Sep 23 '14 19:09

Piet Paulus


People also ask

Does Google OAuth use JWT?

Whether you use the JWT operations or the traditional operations that create opaque string tokens, the basic use of the OAuthV2 policy is the same. You can use JWT access tokens with all of the supported OAuthV2 grant types. See also Introduction to OAuth 2.0.


1 Answers

I just got something similar working on my end. Once you get the user to OAuth you need to store the current user ID. You can do this via datastore or as a parameter if your using taskqueues

from google.appengine.api import users ClientID = users.get_current_user().user_id()

Then with what ever code you later need the OAuth tokens run.

from oauth2client.appengine import CredentialsModel
from oauth2client.appengine import StorageByKeyName 

credentials = StorageByKeyName(CredentialsModel, ClientID, 'credentials').get()
cal = build('calendar', 'v3',http = credentials.authorize(httplib2.Http()))

Then use the cal to do your API calls.

like image 66
Ryan Avatar answered Oct 13 '22 20:10

Ryan