OpenID登录无法在Gmail上下文小工具中使用

时间:2012-12-03 11:50:25

标签: google-app-engine openid gmail-contextual-gadgets

我正在尝试使用我的gmail小工具设置SSO,但我被卡住了。看来即使登录成功弹出窗口,重试请求仍然无法找到用户。

以下是我的处理程序:

编辑:更新了代码。请参阅以下答案中的评论。

# /
class MainPage(BaseHandler):
    def get(self):
        user = users.get_current_user()
        openid = self.request.get('opensocial_viewer_id')
        self.response.headers['Content-Type'] = 'text/plain'
        if user:
            if openid:
                logging.info('Pairing %s with OpenID %s' % (user.email(), openid))
                my_user = MyUser.query(MyUser.openid == openid).get()
                if not my_user:
                    my_user = MyUser(key=ndb.Key('MyUser', user.email()),
                                           email=user.email(),
                                           username=user.email().split('@')[0])
                my_user.openid = openid
                my_user.put()
            self.response.write('Hello, %s! You can close this window.' % user.email())
            return
        self.response.write('Hello, webapp2 World!')

# /openid/get_user
class OpenIdGetUserHandler(webapp2.RequestHandler):
    def get(self):
        self.response.headers['Content-Type'] = 'application/json'
        openid = self.request.get('opensocial_viewer_id')
        user = MyUser.query(MyUser.openid == openid).get()
        if user:
            logging.info('MyUser with OpenID %s found' % openid)
            self.response.out.write(json.dumps({
                'user_exists': True,
                'user_email': user.email
            }))
            return
        logging.info('MyUser with OpenID %s not found. Checking if logged in.' % openid)
        self.response.out.write(json.dumps({
            'user_exists': False,
            'popup': 'https://myapp.appspot.com/openid/sign_in',
            'opensocial_viewer_id': openid
        }))

# /openid/sign_in
class OpenIdSignInHandler(webapp2.RequestHandler):
    def get(self):
        openid = self.request.get('opensocial_viewer_id')
        self.redirect(users.create_login_url(dest_url='/?opensocial_viewer_id=%s' % openid))

# /openid/sign_out
class OpenIdSignOutHandler(webapp2.RequestHandler):
    def get(self):
        self.redirect(users.create_logout_url(dest_url='/'))

javscript(based on this guide):

function fetchData() {
  // Hit the server, passing in a signed request (and OpenSocial ID), to see if we know who the user is.
  osapi.http.get({
    'href' : 'https://wmp-sugarcrm-gadget.appspot.com/openid/get_user',
    'format' : 'json',
    'authz' : 'signed'
  }).execute(handleLoadResponse);
}

function handleLoadResponse(data) {
  // User exists, OpenID must have occurred previously.
  if (data.content.user_exists) {
    //document.getElementById('output').innerHTML = 'user exists';
    showOneSection('main');
    console.log('Logged in');
    init();
  // User doesn't exist, need to do OpenID to match user ID to OpenID.
  } else {
    showOneSection('approval')
    var url_root = data.content.popup;
    // Retrieve the domain of the current user. gadgets.util.getUrlParameters()['parent'] returns a value
    // of of the form: http(s)://mail.google.com/mail/domain.com/html for Gmail (other containers are similar).
    // The example below shows a regular expression for use with Gmail. For Calendar, use this regular
    // expression instead: /calendar\/hosted\/([^\/]+)/
    var domain = gadgets.util.getUrlParameters()['parent'].match(/.+\/a\/(.+)\/html/)[1];

    var url = url_root + '?domain=' + domain;
        url += url + '&opensocial_viewer_id=' + encodeURIComponent(data.content.opensocial_viewer_id);

    var button = document.getElementById('personalize');
    button.setAttribute('href', 'javascript:void(0);');
    button.setAttribute('onclick', 'openPopup("' + url + '")');

  }
}

function openPopup(url) {
  var popup = window.open(url, 'OpenID','height=800,width=600');

  // Check every 100 ms if the popup is closed.
  finishedInterval = setInterval(function() {
    // If the popup is closed, we've either finished OpenID, or the user closed it. Verify with the server in case the
    // user closed the popup.
    if (popup.closed) {
      console.log('popup closed');
      osapi.http.get({
        'href' : 'https://myapp.appspot.com/openid/get_user',
        'format' : 'json',
        'authz' : 'signed'
      }).execute(handleLoadResponse);

      clearInterval(finishedInterval);
    }
  }, 100);
}

// Call fetchData() when gadget loads.
gadgets.util.registerOnLoadHandler(fetchData);

到目前为止,弹出窗口启动,然后我登录,然后重定向到我的应用程序的主页,显示用户的电子邮件地址,如果他已登录。

但是当弹出窗口关闭,因此重试fetchData()时,users.get_current_user()仍会返回None,即使它在弹出窗口中将正确的用户重定向到主页也是如此。

我错过了什么?

1 个答案:

答案 0 :(得分:2)

无法在上下文小工具中使用OpenId ,因为gagdet位于代理所有请求的小工具容器中。这就是指南向您展示弹出解决方法的确切原因。

小工具中的用户由ID 唯一定义。

在弹出窗口中,您可以向服务器发送OpenId请求,因为您突破了小工具容器。将唯一ID发送到服务器,以便将唯一ID链接到服务器上的OpenId用户;

从那时起,您可以使用唯一ID从小工具中发送请求。服务器将知道用户的身份,因为您在通过弹出窗口进行呼叫时链接了唯一ID和身份。

您只需建立关系唯一ID<>如果你以某种方式在服务器上持久存在,则使用弹出窗口进行一次身份识别。