EDIT: There are some updates to the FB documentation, it doesn’t affect the login process a lot, but I decided to rehash this tutorial anyway. Updated tutorial
Access to Github Repository
Facebook authentication is one of the easiest way of authenticating your user without them having to create a full-fledged user profile system. Here is a quick tutorial of how to integrate facebook login with your web.py application.
Here is the basic setup of the application:
import web import json import time import urllib import urlparse FB_APP_SECRET = '' FB_APP_ID = '' urls = [ '/', 'Index', '/li', 'Login', '/lo', 'Logout' ] app = web.application(urls, globals()) def getURL(): return web.ctx.home + web.ctx.fullpath
The login stage of the application requires two main stages: the authentication stage and the retrieval of the access token.
In the authentication stage, the user is redirected to
http://www.facebook.com/dialog/oauth where they will accept all the permissions that the application will require. What is returned will be the code which will be used to retrieve the access token for that particular session.
In the second stage, the user is redirected to
https://graph.facebook.com/oauth/access_token for the access token. The result is read using the
parse_qs function from
urlparse, where the access token is extracted.
The last stage of the login will be extracting the user information for storage in the cookies. Using the access token, the user’s profile information is retrieved from
https://graph.facebook.com/me, where the user id and the user name is stored for display.
class Login: def GET(self): i = web.input(code = None) args = dict(client_id=FB_APP_ID, redirect_uri=getURL()) ### Authentication stage if not i.code: web.seeother('http://www.facebook.com/dialog/oauth?' + urllib.urlencode(args)) return ### Access token stage args['code'] = i.code args['client_secret'] = FB_APP_SECRET req = 'https://graph.facebook.com/oauth/access_token?' + urllib.urlencode(args) res = urlparse.parse_qs(urllib.urlopen(req).read()) tkn = res['access_token'][-1] ### Retrieving profile information req = 'https://graph.facebook.com/me?' + urllib.urlencode(dict(access_token=tkn)) res = json.load(urllib.urlopen(req)) t = time.time() + 7*86400 web.setcookie('fb_uid', res['id'], t) web.setcookie('fb_uname', res['name'], t) web.seeother('/')
Since we are using cookies to store the session details, logging out will just require us to reset the cookies.
class Logout: def GET(self): web.setcookie('fb_uid', '', time.time() - 86400) web.setcookie('fb_uname', '', time.time() - 86400) web.seeother('/')
Displaying the information
After the user have logged in, some of the user information will be stored in the cookies. We will make use of this by displaying the user’s name and profile picture if he is logged in. We do so by checking the state of the cookie variables
fb_uname, if they exist, they will be printed out, else, a login link will be displayed instead.
class Index: def GET(self): html = "<a href="/li">FB Login</a>" uid = web.cookies().get('fb_uid') uname = web.cookies().get('fb_uname') if uid and uname: html = "<img src="https://graph.facebook.com/"+uid+"/picture" alt="" /> <h4>"+uname+"</h4> <a href="/lo">Logout</a>" return ''' <h1>Hi!!!</h1> '''+html+''' '''
There you have it, your own web.py application with facebook authentication.
Things to note
- To integrate a more general form of OAuth system, take a look at the python-oauth2 package
- Never reveal your app secret and id, you never know who is looking
- Original inspiration
Access to Github Repository