2012-12-03 64 views
1

我試圖建立SSO與我的Gmail小工具,但我堅持。看起來,即使在彈出窗口中登錄成功,重試請求以獲取用戶仍然找不到用戶。的OpenID登錄的Gmail上下文小工具無法正常工作

這是我的處理程序:

編輯:更新的代碼。請參閱下面的答案評論。

#/
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即使返回重定向到主頁,在彈出的正確的用戶。

我錯過了什麼?

回答

2

您的不能在上下文小工具中使用OpenId,因爲gagdet存在於代理所有請求的小工具容器中。這就是該指南向您顯示彈出的解決方法的確切原因。

小工具內的用戶是由ID唯一地限定。

從彈出窗口內,您可以可以向服務器發送OpenId請求,因爲您擺脫了小工具容器。沿着唯一的ID發送到服務器,這樣就可以鏈接的唯一ID服務器上的OpenID用戶;

從此,您可以從您的小工具中使用的唯一的ID發送請求。服務器將知道用戶的身份,因爲您在通過彈出窗口進行呼叫時鏈接了唯一ID和身份。

您只需如果你堅持這樣莫名其妙地在服務器上用彈出一次建立關係的唯一ID <>的身份。

+0

謝謝。我更新了我的代碼,並使其工作,但我不確定它是否正確。基本上,當彈出窗口打開時,我將open_id作爲參數,然後將其傳遞到主頁(登錄後的重定向)。在主頁中,我得到'users.get_current_user()',創建一個存儲用戶電子郵件的新記錄和從彈出窗口傳遞的open_id。 – john2x