2012-05-04 94 views
4

我有以下處理程序Facebook的「登錄」(OAuth2用戶)

首先,用戶調用此處理程序和被重定向至Facebook:

class LoginFacebookHandler(BasicHandler): 
    def get(self): 
     user = self.auth.get_user_by_session() 
     if not user: 
      h = hashlib.new('sha512') 
      h.update(str(datetime.now())+"abc") 
      nonce = h.hexdigest() 
      logging.info("hash "+str(nonce)) 
      memcache.set(str(nonce), True, 8600) 
      #facebook_uri = "https://www.facebook.com/dialog/oauth?client_id=%s&redirect_uri=%s&state=%s&scope=%s" % ("20773", "http://upstrackapp.appspot.com/f", str(nonce), "email") 
      data = {"client_id": 20773, "redirect_uri": "http://***.appspot.com/f", "state": str(nonce), "scope": "email"} 
      facebook_uri = "https://www.facebook.com/dialog/oauth?%s" % (urllib.urlencode(data)) 
      self.redirect(facebook_uri) 

後,他授權我的應用程序的Facebook重定向到重定向URI(處理器):

class CreateUserFacebookHandler(BasicHandler): 
    def get(self): 
     state = self.request.get('state') 
     code = self.request.get('code') 
     logging.info("state "+state) 
     logging.info("code "+code) 
     if len(code) > 3 and len(state) > 3: 
      cached_state = memcache.get(str(state)) 
      logging.info("cached_state "+str(cached_state)) 
      if cached_state: 
       #memcache.delete(str(state)) 
       data = { "client_id": 20773, "redirect_uri": "http://***.appspot.com/f", "client_secret": "7f587", "code": str(code)} 
       graph_url = "https://graph.facebook.com/oauth/access_token?%s" % (urllib.urlencode(data)) 
       logging.info("grph url "+graph_url) 

       result = urlfetch.fetch(url=graph_url, method=urlfetch.GET) 
       if result.status_code == 200: 
        fb_response = urlparse.parse_qs(result.content) 
        access_token = fb_response["access_token"][0] 
        token_expires = fb_response["expires"][0] 
        logging.info("access token "+str(access_token)) 
        logging.info("token expires "+str(token_expires)) 
        if access_token: 
         api_data = { "access_token": str(access_token)} 
         api_url = "https://graph.facebook.com/me?%s" % (urllib.urlencode(api_data)) 
         logging.info("api url "+api_url) 
         api_result = urlfetch.fetch(url=api_url, method=urlfetch.GET) 
         if api_result.status_code == 200: 
          api_content = json.loads(api_result.content) 
          user_id = str(api_content["id"]) 
          email = str(api_content["email"]) 
          logging.info("user id "+str(user_id)) 
          logging.info("email "+str(email)) 
          h = hashlib.new('sha512') 
          h.update(str(user_id)+"abc") 
          password = h.hexdigest() 
          expire_data = datetime.now() + timedelta(seconds=int(token_expires)) 
          user = self.auth.store.user_model.create_user(email, password_raw=password, access_token=access_token, token_expires=expire_data, fb_id=user_id) 
         else: 
          self.response.write.out.write("error contacting the graph api") 
        else: 
         self.response.out.write("access token not long enough") 
       else: 
        self.response.out.write("error while contacting facebook server") 
      else: 
       self.response.out.write("error no cached state") 
     else: 
      self.response.out.write("error too short") 

晴這個作品,直到代碼試圖檢索和的access_token我最終得到「錯誤,同時接觸......」。 有趣的是,我登錄所有的URL,狀態等等,所以我進入我的日誌,複製&粘貼urlfetch試圖打開的URL(fb api-> access_token)將其粘貼到我的瀏覽器,並voilà我得到我的access_token +過期。 當代碼嘗試從圖形(圖形/我)中獲取用戶信息時,有時會發生同樣的事情。

+0

您應該記錄result.content以查看您從FB獲得的錯誤,請這樣做並更新問題。 –

回答

1

關鍵問題不在於facebook。 這是AppEngine部署過程。 我總是測試活動代碼中的更改,而不是本地活動,因爲OAuth無法正常工作。 因此,deployment -> flush casche -> flush database進程似乎有一定的延遲,導致工件留下,這使代碼混淆。

因此,如果您必須測試OAuth Live等類似的東西,我建議您將這些更改作爲應用的新版本進行部署,並且在部署之後您應刪除可能在新版本中充當工件的所有數據。

+1

您是否檢出了便於FB登錄的項目simpleauth和engineauth?它們非常好,允許多個不同的OAuth 2.0提供者將用戶實體保存在webapp2用戶模型中。 –

+2

@NickRosencrantz非常感謝Nick,是的,我檢查了這些庫,但是我想自己實現,因爲我對這些庫感覺不舒服。 也他們都基本上做我一樣(webapp2_sessions + webapp2_auth,擴大用戶模型,ndb tada) –