1

我正在使用基于 Python 的Social Cookbook模板来创建 Facebook 应用程序,但我遇到了Canvas 支持的问题,它支持 POST 而不是 GET。Cookbook 示例不包括如何处理此问题。基于阅读此Hello World 示例并查看Run With Friends示例,我能够获取签名请求、读取数据(用户 ID、令牌)并将方法设置为 GET。

然而,随着它的继续,浏览器/龙卷风服务器进入一个循环,它重复运行 LoginHandler。给我一个错误“Firefox 检测到服务器正在以永远不会完成的方式重定向对该地址的请求。” 两天来我一直试图解决这个问题,并想是否有人可以提供帮助 - 这将是 StackOverflow。感谢您在修改社交食谱以支持 Facebook 画布时提供的任何指导。

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
4

1 回答 1

1

好的,这就是我最终做的事情(感谢 oDesk - Haiming Yin 的一些帮助)以及我的一些问题。一方面,在 Mac 上运行 FireFox 的系统禁用了第三方 Cookie。这将导致 Facebook 画布出现问题。在 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>
于 2012-06-06T18:42:08.970 回答