为我的AppEngine应用程序编写OAuth2Callback

时间:2013-12-31 12:53:27

标签: google-app-engine google-oauth webapp2

我想在AppEngine应用程序中实现这种情况:

当用户请求MyPageHandler时,他将被自动重定向到登录页面(如果他没有登录)。然后,如果用户不存在于我们的记录中,我们将要求他提供一些凭证(更确切地说是https://www.googleapis.com/auth/plus.login指定的凭证)。我们存储授权令牌以供将来使用。 用户下次连接时,他会直接登录。

为此,我写了这段代码:

decorator = appengine.OAuth2DecoratorFromClientSecrets(
    'my_client_secret.json',
    scope = 'https://www.googleapis.com/auth/plus.login')

@decorator.oauth_aware
def custom_login_required(handler_method):

    def check_login(self, *args, **kwargs):
        user = users.get_current_user()

        if not user:
            return self.redirect(users.create_login_url(self.request.url))
        else:
            usrs = UsersModel.query(UsersModel.email == users.get_current_user().email()).fetch()

            if len(usrs) == 0:
                user = UsersModel(email =  users.get_current_user().email())
                http = decorator.Http()
                myService = build('plus', 'v1', developerKey=api_key, http = http)
                people_resource = service.people()
                people_document = people_resource.get(userId='me').execute()
                user.gplus_profile = people_document['url']
                user.put()
                handler_method(self, *args, **kwargs)
            else:
                #get the link and avatar
                handler_method(self, *args, **kwargs)

    return check_login

class MyPage(webapp2.RequestHandler):
    @custom_login_required
    def get(self):
         .
         .
         #Some Work
         .
         .

class OAuth2CallbackRequestHandler(decorator.callback_handler()):
    def get(self):
         #I do not know how to make use of this
         pass

谢谢。

2 个答案:

答案 0 :(得分:1)

我终于设法创建OAuth2CallbackHandler以适应我在帖子中指定的场景。以下是具有相同问题的人的解决方案。

class OAuth2CallbackRequestHandler(webapp2.RequestHandler):

@decorator.oauth_aware
def get(self):

    user = users.get_current_user()
    if not user:  #user not signed in
        return self.redirect(users.create_login_url(self.request.url))
    else:         #user signed-in
        usrs = UsersModel.query(UsersModel.email == users.get_current_user().email()).fetch()

        if len(usrs) == 0: #NEW USER
            if len(self.request.get('code')) != 0:  #user gave us permission
                credentials = decorator.flow.step2_exchange(self.request.get('code'))  #exchange user-permissions for credentials
                decorator.set_credentials(credentials)
                if decorator.has_credentials():  #ensuring credentials are setup
                    http = decorator.http()
                    myService = build('plus', 'v1', developerKey = api_key, http = http)

                    user = UsersModel(email =  users.get_current_user().email())
                    people_resource = myService.people()
                    people_document = people_resource.get(userId='me').execute()
                    user.gplus_profile_url = people_document['url']
                    user.gplus_avatar_url = people_document['image']['url']
                    user.display_name = people_document['displayName']
                    user.access_token = credentials.access_token
                    user.refresh_token = credentials.refresh_token #You may need them if you want to update the current information

                    user.put()

                    return self.redirect('/MyPage')
                else:
                    return self.redirect('/oauth2callback')
            else:  #we ask user for permission
                link = decorator.authorize_url()
                return self.redirect(link)

        else:   #USER ALREADY EXISTS
            return self.redirect('/MyPage')


class MyPage(webapp2.RequestHandler):

def get(self):

    if not users.get_current_user():
        self.redirect('/oauth2callback')
        return

    # Continue your work here

答案 1 :(得分:0)

看看

https://developers.google.com/accounts/docs/OAuth2WebServer

您首先在构建URL的部分中执行操作,然后将调用发送到Google,然后您的回调(在redirect_uri参数中指定)执行处理响应部分中的内容。

或者,或许更好,检查并查看是否有适合您的脏工作库。