4

私は次のハンドラーを持っています

最初に、ユーザーはこのハンドラーを呼び出し、Facebookにリダイレクトされます。

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)

彼が私のアプリを承認した後、FacebookはリダイレクトURI(ハンドラー)にリダイレクトします:

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

ほとんどの場合、これはコードがaccess_tokenを取得しようとし、「接続中にエラーが発生する」という結果になるまで機能します。面白いことに、すべてのURLや状態などをログに記録するので、ログに移動し、urlfetchが開こうとしたURLをコピーして貼り付け(fb api-> access_token)、ブラウザーに貼り付けて、access_token+の有効期限が切れます。コードがグラフ(graph / me)からユーザー情報を取得しようとすると、同じことが起こることがあります。

4

1 に答える 1

1

重要な問題はFacebookではありません。これはAppEngineのデプロイプロセスです。OAuthが適切に機能しないため、ローカルではなくライブでコードの変更を常にテストしました。そのため、deployment -> flush casche -> flush databaseプロセスには一定の遅延があり、アーティファクトが残っているように見え、コードが混乱していました。

したがって、OAuthライブなどをテストする必要がある場合は、変更をアプリの新しいバージョンとしてデプロイすることをお勧めします。デプロイ後に、新しいバージョンでアーティファクトとして機能する可能性のあるすべてのデータを削除する必要があります。

于 2012-05-04T22:43:34.163 に答える