2011-10-04 72 views
0

我有一個可怕的bug,我把bounty on,現在我減少到最簡單的複製情況。至少有一個可以重現它:D一些信息:實體FUser不會填充實體,JavaScript按鈕在用戶登錄/註銷之間切換,從日誌中您可能會告訴我流程出了什麼問題。爲什麼current_user沒有?

2011-10-04 17:34:14.398 /example 200 10ms 0cpu_ms 0kb Mozilla/5.0 (X11; Linux x86_64; rv:2.0) Gecko/20100101 Firefox/4.0 

213.89.134.0 - - [04/Oct/2011:13:34:14 -0700] "GET /example HTTP/1.1" 200 694 - "Mozilla/5.0 (X11; Linux x86_64; rv:2.0) Gecko/20100101 Firefox/4.0" "www.koolbusiness.com" ms=11 cpu_ms=0 api_cpu_ms=0 cpm_usd=0.000157 instance=00c61b117c837db085d58acd70ffae167a06 

D 2011-10-04 17:34:14.395 

logging current_userNone 

的.py

"""A barebones AppEngine application that uses Facebook for login.""" 

FACEBOOK_APP_ID = "164355773607006" 
FACEBOOK_APP_SECRET = "642f15e4324b45661e1049d5b139cb0" 

import facebook 
import os.path 
import wsgiref.handlers 
import logging 
from google.appengine.ext import db 
from google.appengine.ext import webapp 
from google.appengine.ext.webapp import util 
from google.appengine.ext.webapp import template 


class FUser(db.Model): 
    id = db.StringProperty(required=True) 
    created = db.DateTimeProperty(auto_now_add=True) 
    updated = db.DateTimeProperty(auto_now=True) 
    name = db.StringProperty(required=True) 
    profile_url = db.StringProperty(required=True) 
    access_token = db.StringProperty(required=True) 


class BaseHandler(webapp.RequestHandler): 
    """Provides access to the active Facebook user in self.current_user 

    The property is lazy-loaded on first access, using the cookie saved 
    by the Facebook JavaScript SDK to determine the user ID of the active 
    user. See http://developers.facebook.com/docs/authentication/ for 
    more information. 
    """ 
    @property 
    def current_user(self): 
     if not hasattr(self, "_current_user"): 
      self._current_user = None 
      cookie = facebook.get_user_from_cookie(
       self.request.cookies, FACEBOOK_APP_ID, FACEBOOK_APP_SECRET) 
     logging.debug("logging cookie"+str(cookie)) 
      if cookie: 
       # Store a local instance of the user data so we don't need 
       # a round-trip to Facebook on every request 
       user = FUser.get_by_key_name(cookie["uid"]) 
       logging.debug("user "+str(user)) 

       if not user: 
        graph = facebook.GraphAPI(cookie["access_token"]) 
        profile = graph.get_object("me") 
        user = FUser(key_name=str(profile["id"]), 
           id=str(profile["id"]), 
           name=profile["name"], 
           profile_url=profile["link"], 
           access_token=cookie["access_token"]) 
        user.put() 
       elif user.access_token != cookie["access_token"]: 
        user.access_token = cookie["access_token"] 
        user.put() 
       self._current_user = user 
     return self._current_user 


class HomeHandler(BaseHandler): 
    def get(self): 
     path = os.path.join(os.path.dirname(__file__), "example.html") 
    logging.debug("logging current_user"+str(self.current_user)) 
     args = dict(current_user=self.current_user, 
        facebook_app_id=FACEBOOK_APP_ID) 
     self.response.out.write(template.render(path, args)) 


def main(): 
    util.run_wsgi_app(webapp.WSGIApplication([(r"/example", HomeHandler)])) 


if __name__ == "__main__": 
    main() 


<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> 
<html xmlns="http://www.w3.org/1999/xhtml"> 
    <head> 
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/> 
    <title>Facebook Example</title> 
    </head> 
    <body> 
    <fb:login-button autologoutlink="true"></fb:login-button> 

    {% if current_user %} 
     <p><a href="{{ current_user.profile_url }}"><img src="http://graph.facebook.com/{{ current_user.id }}/picture?type=square"/></a></p> 
     <p>Hello, {{ current_user.name|escape }}</p> 
    {% endif %} 



    <div id="fb-root"></div> 
    <script> 
     window.fbAsyncInit = function() { 
     FB.init({appId: '{{ facebook_app_id }}', status: true, cookie: true, 
       xfbml: true}); 
     FB.Event.subscribe('{% if current_user %}auth.logout{% else %}auth.login{% endif %}', function(response) { 
      window.location.reload(); 
     }); 
     }; 
     (function() { 
     var e = document.createElement('script'); 
     e.type = 'text/javascript'; 
     e.src = document.location.protocol + '//connect.facebook.net/en_US/all.js'; 
     e.async = true; 
     document.getElementById('fb-root').appendChild(e); 
     }()); 
    </script> 
    </body> 
</html> 

更新

我仍然沒有得到用戶對象,改變了HomeHandler這個

class HomeHandler(BaseHandler): 
    def get(self): 
     path = os.path.join(os.path.dirname(__file__), "example.html") 
    logging.debug("logging current_user"+str(self.current_user)) 
     args = dict(current_user=self.current_user, 
        facebook_app_id=FACEBOOK_APP_ID) 

    user = facebook.get_user_from_cookie(self.request.cookies, FACEBOOK_APP_ID, FACEBOOK_APP_SECRET) 

     if not user: 
     logging.debug("no user") 

    if user: 
     graph = facebook.GraphAPI(user["access_token"]) 
     profile = graph.get_object("me") 
     friends = graph.get_connections("me", "friends") 
    logging.debug("logging profile"+str(profile)) 
     self.response.out.write(template.render(path, args)) 
+1

不要忘記不要使用您剛發佈的fb祕密! –

回答

1

關於@Shay Erlichmen的觀察,上述代碼不應該由於前幾天Facebook的更改而起作用。正如我在原來的提問時指出,有已被修改,以支持新的身份驗證機制Facebook的蟒蛇SDK的一個版本 - 見

https://gist.github.com/1190267

具體的地方,這不同於舊版本在get_user_from_cookie()方法中。如果您仍在使用舊版本的facebook python SDK,則應查找fbs_APPID Cookie,但找不到它並返回None - 因此cookie永遠不會分配值_current_user會保留在該方法開始時分配的None狀態。

您可以執行的一項檢查是查看瀏覽器中的Cookie - 您應該看到舊的庫不處理的新的fbsr_APPID Cookie。

1

的Facebook切換到OAuth2.0 on October 1,2011 ,這個代碼是舊的,應該可以工作了。