【问题标题】:Write an OAuth2Callback for my AppEngine application为我的 AppEngine 应用程序编写 OAuth2Callback
【发布时间】:2014-01-18 09:51:38
【问题描述】:

我想让这个场景发生在 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

谢谢。

【问题讨论】:

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


    【解决方案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
    

    【讨论】:

    • 这是一个很好的问题和答案。不过,我看不到您在哪里告诉装饰器请求 refresh_token 。当我尝试这个时,我总是得到其中没有 refresh_token 的凭据
    • 您可能已经生成了一个 refresh_token(当您第一次尝试此代码时)并且您还没有保存它。请记住,每个用户不能生成超过 1 个刷新令牌。因此,请尝试更改您登录时使用的 user_account 并获取刷新令牌(您会看到它)。
    • 谢谢你,你是对的。我不得不撤销我的测试用户的所有权限,然后出现了 refresh_token。
    【解决方案2】:

    看看

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

    您首先执行形成 URL 部分中的内容,然后调用 google,然后您的回调(在 redirect_uri 参数中指定)执行处理响应部分中的内容。

    或者,也许更好,检查一下是否有一个库可以为你做这些脏活。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2023-03-12
      • 1970-01-01
      • 2013-02-18
      • 2017-08-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多