2012-06-02 44 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> 
相关问题