2012-06-02 75 views
1

我使用基於Python的Social Cookbook模板來創建一個Facebook應用程序,但我遇到了問題Canvas support which does a POST instead of a GET。 Cookbook示例不包括如何處理這個問題。根據讀取此Hello World example並查看Run With Friends示例,我能夠獲得簽名的請求,讀取數據(用戶ID,令牌),並將方法設置爲GET。Facebook的帆布應用程序 - 圓形登錄重定向

但是,繼續瀏覽器/龍捲風服務器進入一個循環,它重複運行LoginHandler。給我一個錯誤「Firefox已經檢測到服務器正以一種永遠不會完成的方式重定向這個地址的請求。」我一直試圖弄清楚這兩天,並認爲是否有人可以幫助 - 這將是StackOverflow。感謝您提供的修改Social Cookbook以支持Facebook Canvas的任何指導。

class BaseHandler(tornado.web.RequestHandler): 

    def initialize(self): 
     self.init_facebook() 

    def init_facebook(self): 
     # initial facebook request comes in as a POST with a signed_request 
     signed_request = self.get_argument('signed_request', None) 
     if signed_request and self.request.method == u'POST': 
      app_secret = options.facebook_app_secret 
      data = load_signed_request(signed_request, app_secret) 
      user_id = data.get(u"user_id") 
      mytoken = data.get(u"oauth_token") 
      print mytoken 
      self.set_secure_cookie("uid", user_id) 
      self.request.method = u'GET' # causes loss of request.POST data 

回答

1

好吧,這就是我最終做的事情(感謝oDesk的一些幫助 - Haiming Yin)以及我的一些問題。首先,Mac上運行FireFox的系統禁用了第三方Cookie。這會導致Facebook Canvas出現問題。在IE上,您必須設置正確的P3P標頭。因此,所有這些結合起來造成了很大的麻煩。

class BaseHandler(tornado.web.RequestHandler): 
    @property 
    def prepare(self): 
     self.set_header('P3P', 'CP="HONK"') 

    def initialize(self): 
     if self.request.full_url() == "http://mydomain/a/facebook/": 
      self.request.protocol = "https" 
     self.init_facebook() 

    def init_facebook(self): 
     """Sets up the request specific Facebook and User instance""" 

     # initial facebook request comes in as a POST with a signed_request 
     signed_request = self.get_argument('signed_request', None) 
     if signed_request and self.request.method == u'POST': 
      app_secret = options.facebook_app_secret 
      data = load_signed_request(signed_request, app_secret) 
      user_id = data.get(u"user_id") 
      if user_id: 
       self.set_secure_cookie("uid", user_id) 
      self.request.method = u'GET' 

class FacebookCanvasHandler(HomeHandler): 
    def get(self, *args, **kwds): 
     logging.info("Facebook Canvas called.") 
     if not self.current_user: 
      logging.info("Need user grant permission, redirect to oauth dialog.") 
      logging.info(self.settings.get("facebook_canvas_id")) 
      oauth_url = self.get_login_url(self.settings.get("facebook_canvas_id")) 
      logging.info(oauth_url) 
      self.render("canvas_oauth.html", oauth_url=oauth_url) 
     else: 
      super(FacebookCanvasHandler, self).get(*args, **kwds) 

def load_signed_request(signed_request, app_secret): 
    try: 
     sig, payload = signed_request.split(u'.', 1) 
     sig = base64_url_decode(sig) 
     data = json.loads(base64_url_decode(payload)) 

     expected_sig = hmac.new(app_secret, msg=payload, digestmod=hashlib.sha256).digest() 

     if sig == expected_sig and data[u'issued_at'] > (time.time() - 86400): 
      return data 
     else: 
      return None 
    except ValueError, ex: 
     return None 

def base64_url_decode(data): 
    data = data.encode(u'ascii') 
    data += '=' * (4 - (len(data) % 4)) 
    return base64.urlsafe_b64decode(data) 

canvans_oauth.html

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
     "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:fb="http://www.facebook.com/2008/fbml"> 
<head> 
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> 
    <title> 
     Page Title 
    </title> 
    <meta name="description" content="description of the page" /><meta name="keywords" content="" /><meta name="viewport" content="width=device-width" /> 
    <link rel="icon" type="image/png" href="/static/favicon.ico" /> 
    <script> 
     window.top.location = "{% raw oauth_url %}"; 
    </script> 

</head> 

<body id="inner_body" class="inner_body"> 
redirecting to oauth... 
</body> 
</html> 
相關問題