【问题标题】:Understanding "runwithfriends" facebook-app sample code了解“runwithfriends”facebook-app 示例代码
【发布时间】:2011-12-30 03:11:44
【问题描述】:

这是我的第一次网络编程经验,所以我希望我的问题听起来不是很愚蠢。我被这个问题困扰了很多天。

我正在尝试理解示例代码: https://github.com/facebook/runwithfriends

但是我不太了解信息流的工作原理以及如何修改该示例(即代码的工作原理)。

例如,在下面这段代码中:

class RecentRunsHandler(BaseHandler):
"""Show recent runs for the user and friends"""
def get(self):
    if self.user:
        friends = {}
        for friend in select_random(
                User.get_by_key_name(self.user.friends), 30):
            friends[friend.user_id] = friend

        self.render(u'runs',
            friends=friends,
            user_recent_runs=Run.find_by_user_ids(
                [self.user.user_id], limit=5),
            friends_runs=Run.find_by_user_ids(friends.keys()),
        )
    else:
        self.render(u'welcome')

据我了解(连同 HTML)对于向正在使用同一应用程序的朋友展示很有用,如果我理解正确,这里是必不可少的部分:

*friends_runs=Run.find_by_user_ids(friends.keys())*

但是,如果我想向任何给定的朋友展示呢?我该怎么做?

总结一下,我想知道:

1- 代码流如何工作? (看不懂here的解释)

2- 我如何操作代码以获取,例如,显示用户的朋友列表(不必使用相同的应用程序)? 此外,我可以显示按某些特征(例如性别)过滤的朋友吗?

非常感谢!

【问题讨论】:

    标签: python google-app-engine facebook-apps


    【解决方案1】:

    我从https://gist.github.com/1190267获取的用于facebook的python“SDK” 并将其与示例应用程序中的代码相结合,以实现我想要的画布应用程序和网站使用的功能。

    这取决于您是使用带有网站的 Facebook 还是使用画布应用程序。对于画布应用程序,您可能可以使用 javascript SDK 做得很好,但对于“使用 facebook 登录”,我需要关闭 javascript 的服务器端逻辑,因此我已经完成了该解决方案,其中包含您可能需要了解的详细信息。您可以尝试对该特定应用程序“runwithfriends”进行小幅更改,以了解哪些代码做了什么。您正在查看的项目包含一些过时的做法:

    • 现在使用 webapp2 的内置函数而不是 FB 示例应用程序附带的代码可能更可取获取和设置 cookie

    • 现在使用 OAuth 2.0 完成登录和注销,因此您正在查看的登录系统可能已经过时,您需要使用描述为 here 的 OAuth 2.0。我更喜欢登录/注销服务器端,所以我按照 FB 教程中提到的身份验证步骤执行了 OAuth 2.0 纯 python 解决方案来登录/注销。我必须清除 cookie 才能注销未记录的用户。

    • 要升级到 python 2.7,我还必须进行修改,以便 HTTP 标头不会转换为 unicode。我不知道为什么,否则它会抱怨标题“不是字符串”

    要更详细地回答您的具体问题:

    1) 您发布的 requesthandler 类是 BaseHandler 的子类,因此要完全了解它的作用,您可以查看 BaseHandler 类,因为您发布的是 BAseHandler。 BaseHandler 使用 django 模板进行渲染,如果您愿意,可以将模板引擎切换到推荐的 jinja2。此外,代码访问从 BaseHandler 继承的用户对象并对其进行一些操作并将其呈现给模板。您可以尝试制作自己的请求处理程序,子类 BaseHandler 并做您想做的事。

    2) 我可以操纵代码,但我不是专家,所以你也应该能够做到。我想要一个简单的 FB 应用程序来显示随机图像,我可以操纵它通过 blob 选择随机图像并渲染到模板,同时保留 facebook 基本功能。用于使用 Graph API 获取用户的函数我这样做:

    def parse_signed_request(signed_request, secret):
        """
        Parse signed_request given by Facebook (usually via POST),
        decrypt with app secret.
    
        Arguments:
        signed_request -- Facebook's signed request given through POST
        secret -- Application's app_secret required to decrpyt signed_request
        """
    
        if '.' in signed_request:
            (esig, payload) = signed_request.split('.')
        else:
            return {}
    
        sig = urlsafe_b64decode(str(esig))
        data = _parse_json(urlsafe_b64decode(str(payload)))
    
        if not isinstance(data, dict):
            raise SignedRequestError('Pyload is not a json string!')
            return {}
    
        if data['algorithm'].upper() == 'HMAC-SHA256':
            if hmac.new(secret, payload, hashlib.sha256).digest() == sig:
                return data
        else:
    
            raise SignedRequestError('Not HMAC-SHA256 encrypted!')
    
        return {}
    
    
    def get_user_from_cookie(cookies, app_id, app_secret):
        """Parses the cookie set by the official Facebook JavaScript SDK.
    
        cookies should be a dictionary-like object mapping cookie names to
        cookie values.
    
        If the user is logged in via Facebook, we return a dictionary with the
        keys "uid" and "access_token". The former is the user's Facebook ID,
        and the latter can be used to make authenticated requests to the Graph API.
        If the user is not logged in, we return None.
    
        Download the official Facebook JavaScript SDK at
        http://github.com/facebook/connect-js/. Read more about Facebook
        authentication at http://developers.facebook.com/docs/authentication/.
        """
        cookie = cookies.get('fbsr_' + app_id, '')
        if not cookie:
            return None
        response = parse_signed_request(cookie, app_secret)
        if not response:
            return None
    
        args = dict(code=response['code'], client_id=app_id,
                    client_secret=app_secret, redirect_uri='')
    
        file = \
            urllib.urlopen('https://graph.facebook.com/oauth/access_token?'
                           + urllib.urlencode(args))
        try:
            token_response = file.read()
        finally:
            file.close()
    
        access_token = cgi.parse_qs(token_response)['access_token'][-1]
        logging.debug('returning cookie')
        return dict(uid=response['user_id'], access_token=access_token)
    

    有关 API 的完整文档,请参阅 http://developers.facebook.com/docs/api。您可以通过http://github.com/facebook/connect-js/获取官方的 Facebook JavaScript SDK

    我现在正在编写代码以将 webapp2_extras.auth 帐户与 facebook 同步,以便自定义帐户和 facebook 帐户可以共存,我们正在webapp2 groups 和类别中讨论解决方案。我目前的做法是将推荐的current_user 添加到 basehandler 中,并将其用作 FB 身份,同时“合并”我的类 FBUser,这是一个自定义类,用于授权我的网站和/或画布应用程序的 facebook 用户与 webapp2_extras.auth.models.User 同步,这是一个 expando 模型,因此它可以添加它没有的属性,例如 facebookid、firstname、lastname 等。

    @property
    def current_user(self):
        if not hasattr(self, '_current_user'):
            self._current_user = None
            cookie = get_user_from_cookie(self.request.cookies,
                    facebookconf.FACEBOOK_APP_ID,
                    facebookconf.FACEBOOK_APP_SECRET)
            if cookie:
    
                # Store a local instance of the user data so we don't need
                # a round-trip to Facebook on every request
                user = FBUser.get_by_key_name(cookie['uid'])
                if not user:
                    graph = GraphAPI(cookie['access_token'])
                    profile = graph.get_object('me')
                    user = FBUser(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
    

    您还可以使用会话对象解决您的身份验证问题,并围绕它构建您的身份验证系统。这就是我在使用自定义帐户和 facebook 帐户时所做的事情,欢迎您在my repository 了解更多代码示例,如何使用 python 2.7 将 facebook 与 google 应用程序引擎集成。

    【讨论】:

    • 谢谢。你的回答太棒了!您是否建议我使用或从另一个示例项目开始?因为,正如你提到的,这个项目包含一些过时的做法。也许gist.github.com/1190267 更适合像我这样的新手。我来自 C++ 低级编程,所以 python 和一般的网络编程对我来说是新的。
    • 我建议你从纯 Javascript SDK 开始,因为它很容易得到结果。然后你可以像我一样做,把 Javascript 处理移到服务器上。您可以尝试将所有内容升级到 webapp2 并在 webapp2 组groups.google.com/forum/#!forum/webapp2 中关注我们的进度
    猜你喜欢
    • 1970-01-01
    • 2016-09-13
    • 2011-11-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-05-22
    • 2020-11-09
    相关资源
    最近更新 更多