1

我正在编写一个 python 桌面应用程序,它将访问用户的 facebook 照片。该应用程序当前支持 flickr,它使用类似的 oauth 身份验证过程,但我正在努力弄清楚如何为 facebook 验证应用程序。对于 flickr,基本步骤是:

  1. 应用在身份验证页面上打开浏览器
  2. 用户授予应用访问该帐户的权限
  3. 应用程序接收一个令牌作为 http 响应,然后可以与 flickr 的 api 一起使用

我希望 facebook 也有类似的东西,但我无法弄清楚。

有多种用于 python 的 facebook API 库,例如 Pyfb,它提供了一种访问图形数据的简单方法,但它们都没有提供一种明显的方法来执行上述身份验证步骤并检索可以使用的令牌。这是来自 Pyfb 的示例,它假定用户令牌将由用户手动输入,这对于桌面应用程序来说是完全荒谬的......

from pyfb import Pyfb

#Your APP ID. You Need to register the application on facebook
#http://developers.facebook.com/
FACEBOOK_APP_ID = 'YOUR_APP_ID'

pyfb = Pyfb(FACEBOOK_APP_ID)

#Opens a new browser tab instance and authenticates with the facebook API
#It redirects to an url like  http://www.facebook.com/connect/login_success.html#access_token=[access_token]&expires_in=0
pyfb.authenticate()

#Copy the [access_token] and enter it below
token = raw_input("Enter the access_token\n")

#Sets the authentication token
pyfb.set_access_token(token)

#Gets info about myself
me = pyfb.get_myself()
4

1 回答 1

2

这是回答我自己的问题的机会。

首先,上面的代码片段不起作用的原因。对 pyfb.authenticate 的调用会在默认浏览器中打开身份验证链接。用户登录并允许应用程序访问后,facebook 应该将浏览器中的 URL 重定向到类似

https://www.facebook.com/connect/login_success.html#access_token=ACCESS_TOKEN&
    expires_in=SOMETIME

在 pyfb 代码示例中,用户应该从 URL 栏中复制访问令牌,一切都应该很好。但是......大概是因为一些安全问题,facebook 会执行一些 Javascript 恶作剧,而这些恶作剧会给你留下:

https://www.facebook.com/connect/blank.html#_=_

(事实证明,您可以通过在某些浏览器上挖掘浏览器历史记录来解决此问题——请参阅https://bugs.kde.org/show_bug.cgi?id=319252

桌面应用程序的解决方案是在应用程序中打开 Web 视图。Javascript 代码显然会正确检测到您正在应用程序中进行身份验证,并使用令牌吐出完整的 URL。下面是一个使用 Python gtk 和 webkit 的示例:

import gtk
import webkit

view = webkit.WebView()

sw = gtk.ScrolledWindow()
sw.add(view)

win = gtk.Window(gtk.WINDOW_TOPLEVEL)
win.add(sw)
win.show_all()
win.connect("destroy", lambda *args:gtk.main_quit())

client_id = 'XXXXXXXXXXXXX' #your unique app id
auth_url = 'https://www.facebook.com/dialog/oauth?response_type=token&client_id=%s&redirect_uri=https://www.facebook.com/connect/login_success.html'%(client_id,)
view.open(auth_url)
def load_finished(view,frame):
    #function will print the url with token second time
    print frame.get_uri()

view.connect("document-load-finished",load_finished)
gtk.main()
于 2013-10-15T19:44:24.607 回答