2012-06-02 2 views
1

Я использую шаблон Social Cookbook на основе Python для создания приложения Facebook, но у меня проблема с Canvas support which does a POST instead of a GET. В примере поваренной книги не указано, как справиться с этим. Основываясь на чтении этого Hello World example и глядя на пример Run With Friends, я могу получить подписанный запрос, прочитать данные (идентификатор пользователя, токен) и установить метод GET.Facebook Canvas App - Circular Login Redirect

Однако, как он продолжает, сервер Browser/Tornado переходит в цикл, где он неоднократно запускает LoginHandler. Предоставление мне ошибки «Firefox обнаружил, что сервер перенаправляет запрос на этот адрес таким образом, который никогда не будет завершен». Я пытался понять это в течение двух дней и подумал, может ли кто-нибудь помочь - это будет StackOverflow. Благодарим за любые рекомендации, которые вы могли бы внести в модификацию социальной кулинарной книги для поддержки 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

Итак, вот что я в конечном итоге делает (благодаря некоторой помощи со стороны фрилансеров - Haiming Инь) и то, что некоторые из моих вопросов были. Во-первых, система, работающая с FireFox на Mac, отключила сторонние файлы cookie. Это вызовет проблемы с Canvas 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>