2011-10-04 8 views
0

나는 을 넣은 끔찍한 bug을 가지고 있으며, 이제 나는 복제의 가장 단순한 경우를 줄입니다. 일부 정보 : 엔티티 FUser가 엔티티를 채우지 않고 javascript 버튼이 로그인/로그 아웃을 apprioriately로 전환하고 로그에서 나에게 흐름의 문제점을 알려줄 수 있습니다.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 

는 평

"""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> 

업데이트

나는 여전히 사용자 개체를 얻을이

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 secret를 사용하지 않는 것을 잊지 마십시오! –

답변

1

@Shay Erlichmen의 관찰과 관련하여 며칠 전에 페이스 북의 변경으로 인해 위의 코드가 작동하지 않아야합니다. 이전 버전 인에서

https://gist.github.com/1190267

이 다른 특정 장소를 참조 - 나는 원래의 질문에 지적한 바와 같이, 새로운 인증 메커니즘을 지원하도록 수정 된 페이스 북의 파이썬 SDK의 버전이 get_user_from_cookie() 방법. 여전히 facebook python SDK의 이전 버전을 사용하고 있다면이 쿠키는 fbs_APPID 쿠키를 찾아서 찾지 않고 None을 반환해야합니다. 따라서 은 None 상태를 메서드 시작시 할당 된 값으로 유지합니다.

브라우저에서 쿠키를 살펴 보는 것입니다. 오래된 라이브러리에서 처리하지 않는 새로운 fbsr_APPID 쿠키가 표시되어야합니다.

1

페이스 북에 HomeHandler을 변경하지 않는 OAuth2.0 on October 1,2011로 전환 이 코드는 낡아서 더 이상 작동하지 않아야합니다.

관련 문제