dlm
dlm

Reputation: 4244

Get facebook user/app token in a python desktop app

I am writing a python desktop app that will access a user's facebook photos. The app currently supports flickr, which uses a similar oauth authentication process, but I am struggling to figure out how to authenticate the app for facebook. For flickr, the basic steps are:

  1. App opens a browser on the authentication page
  2. user gives the app permission to access the account
  3. App receives a token as a http response that can then be used with flickr's api

I am hoping that there is something similar for facebook, but I haven't been able to figure it out.

There are a variety of facebook API libraries for python, such as Pyfb, which provides a simple way of accessing graph data, but none of them provide an obvious way to do the authentication steps above and retrieve a token that can be used. Here's the example from Pyfb, which presumes that the user token will be manually entered by the user, which is totally ridiculous for a desktop app...

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

Upvotes: 1

Views: 2461

Answers (1)

dlm
dlm

Reputation: 4244

Here's a shot at answering my own question.

First, the reason the code fragment above doesn't work. The call to pyfb.authenticate opens the authentication link in the default browser. After the user logs in and allows the app access, facebook is supposed to redirect the URL in the browser to something like

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

In the pyfb code sample, the user is supposed to copy the access token from the URL bar and all should be well. But... presumably because of some security concerns, facebook will perform some Javascript shenanigans which will instead leave you with:

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

(It turns out that you can work around this by digging through the browser history on some browsers -- see https://bugs.kde.org/show_bug.cgi?id=319252)

The solution to this for a desktop app is to open a web view within the app. The Javascript code apparently will correctly detect you are authenticating within an app and spit out the full URL with token. So here's an example using Python gtk and 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()

Upvotes: 2

Related Questions