Web.py Application – FB Authentication

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

Introduction

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

Logging In

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

Logging Out

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_uid and 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+'''


'''

Conclusion

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

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s