2012-05-04 5 views
4

I가 다음 핸들러페이스 북 "로그인"(OAuth2를)

먼저 사용자가이 핸들러를 호출하고 페이스 북으로 리디렉션됩니다 : 그는 내 응용 프로그램의 페이스 북이로 리디렉션 허가 후

class LoginFacebookHandler(BasicHandler): 
    def get(self): 
     user = self.auth.get_user_by_session() 
     if not user: 
      h = hashlib.new('sha512') 
      h.update(str(datetime.now())+"abc") 
      nonce = h.hexdigest() 
      logging.info("hash "+str(nonce)) 
      memcache.set(str(nonce), True, 8600) 
      #facebook_uri = "https://www.facebook.com/dialog/oauth?client_id=%s&redirect_uri=%s&state=%s&scope=%s" % ("20773", "http://upstrackapp.appspot.com/f", str(nonce), "email") 
      data = {"client_id": 20773, "redirect_uri": "http://***.appspot.com/f", "state": str(nonce), "scope": "email"} 
      facebook_uri = "https://www.facebook.com/dialog/oauth?%s" % (urllib.urlencode(data)) 
      self.redirect(facebook_uri) 

URI (핸들러)를 리디렉션 : 코드는 access_token이를 검색하려고 내가 그만 둘 때까지

class CreateUserFacebookHandler(BasicHandler): 
    def get(self): 
     state = self.request.get('state') 
     code = self.request.get('code') 
     logging.info("state "+state) 
     logging.info("code "+code) 
     if len(code) > 3 and len(state) > 3: 
      cached_state = memcache.get(str(state)) 
      logging.info("cached_state "+str(cached_state)) 
      if cached_state: 
       #memcache.delete(str(state)) 
       data = { "client_id": 20773, "redirect_uri": "http://***.appspot.com/f", "client_secret": "7f587", "code": str(code)} 
       graph_url = "https://graph.facebook.com/oauth/access_token?%s" % (urllib.urlencode(data)) 
       logging.info("grph url "+graph_url) 

       result = urlfetch.fetch(url=graph_url, method=urlfetch.GET) 
       if result.status_code == 200: 
        fb_response = urlparse.parse_qs(result.content) 
        access_token = fb_response["access_token"][0] 
        token_expires = fb_response["expires"][0] 
        logging.info("access token "+str(access_token)) 
        logging.info("token expires "+str(token_expires)) 
        if access_token: 
         api_data = { "access_token": str(access_token)} 
         api_url = "https://graph.facebook.com/me?%s" % (urllib.urlencode(api_data)) 
         logging.info("api url "+api_url) 
         api_result = urlfetch.fetch(url=api_url, method=urlfetch.GET) 
         if api_result.status_code == 200: 
          api_content = json.loads(api_result.content) 
          user_id = str(api_content["id"]) 
          email = str(api_content["email"]) 
          logging.info("user id "+str(user_id)) 
          logging.info("email "+str(email)) 
          h = hashlib.new('sha512') 
          h.update(str(user_id)+"abc") 
          password = h.hexdigest() 
          expire_data = datetime.now() + timedelta(seconds=int(token_expires)) 
          user = self.auth.store.user_model.create_user(email, password_raw=password, access_token=access_token, token_expires=expire_data, fb_id=user_id) 
         else: 
          self.response.write.out.write("error contacting the graph api") 
        else: 
         self.response.out.write("access token not long enough") 
       else: 
        self.response.out.write("error while contacting facebook server") 
      else: 
       self.response.out.write("error no cached state") 
     else: 
      self.response.out.write("error too short") 

는 대부분이 작품 "접촉하는 동안 오류가 ....". 우스운 일은 모든 로그, 상태 등을 기록하여 로그에 기록합니다. & urlfetch가 열려고 시도한 URL (fb api-> access_token)을 브라우저에 붙여 넣으면 내 access_token이 보입니다. + 만료됩니다. 코드가 그래프 (그래프/me)에서 사용자 정보를 가져 오려고 할 때도 똑같은 일이 발생합니다.

+0

FB에서 어떤 오류가 발생했는지 확인하려면 result.content를 기록해야합니다. 그렇게하고 질문을 업데이트하십시오. –

답변

1

중요한 문제는 페이스 북이 아닙니다. AppEngine 배포 프로세스입니다. OAuth가 제대로 작동하지 않아 항상 로컬이 아닌 코드의 변경 사항을 테스트했습니다. 따라서 deployment -> flush casche -> flush database 프로세스가 특정 지연으로 인해 아티팩트가 남아있어 코드가 혼란스러워졌습니다.

OAuth 라이브와 같은 것들을 테스트해야한다면, 새로운 버전의 앱으로 변경 사항을 배치하는 것이 좋을 것입니다. 배포 후에는 새 버전에서 아티팩트로 작용할 수있는 모든 데이터를 삭제해야합니다.

+1

FB 로그인을 쉽게하는 simpleauth 및 engineauth 프로젝트를 확인 했습니까? 그것들은 상당히 좋으며 여러 다른 OAuth 2.0 제공자가 webapp2 사용자 모델에서 User 엔티티를 저장할 수 있습니다. –

+2

@NickRosencrantz 대단히 감사합니다. Nick, 예. 그런 라이브러리를 확인했지만, 저는 그 libs에 익숙하지 않았기 때문에이 라이브러리를 직접 구현하고 싶었습니다. 또한 이들 모두 기본적으로 내가하는 것과 똑같은 일을합니다 (webapp2_sessions + webapp2_auth, 사용자 모델 확장, ndb tada) –