Authorizing a user using Facebook OAuth 2.0 based login it’s pretty straighfoard. This is for the person who asked a question on stackoverflow.com I hope it helps.
Add the apikey, appid and secret of my Facebook app to the development.ini file
facebook.apikey = 42bc5a4051b274ede5cb73a6cd6fad56
facebook.secret = a355e66e8c0293390896a170f9d5r4c3
facebook.appid = 20894420580890
Configure my model/init.py file:
from PRJNAME.model.meta import Session, Base
from sqlalchemy import Column
from sqlalchemy import Integer
from sqlalchemy import Unicode
from sqlalchemy import Table
from sqlalchemy import Text
from sqlalchemy import Unicode
from sqlalchemy import BigInteger
from sqlalchemy import TIMESTAMP
from sqlalchemy import ForeignKey,ForeignKeyConstraint
from sqlalchemy.orm import mapper
import datetime
def init_model(engine):
"""Call me before using any of the tables or classes in the model"""
Session.configure(bind=engine,autoflush=True,autocommit=False)
def now():
return datetime.datetime.now()
social_user = Table('social_user', Base.metadata,
Column('id', Integer, primary_key=True),
Column('oauth_provider', Text(), nullable=False),
Column('oauth_id', Text() , nullable=False),
Column('username', Unicode(50), nullable=False),
Column('access_token', Unicode(200)),
Column('created', TIMESTAMP(timezone=True), default=now()),
)
class Social(object):
pass
mapper(Social,social_user)
Download the Facebook Python-SDK
https://github.com/facebook/python-sdk
And save it on your project lib directory
Create a controller named account
~$ paster controller account
Add a view named login and render a login button
I’ll use https://graph.facebook.com/oauth/authorize as the url to start the authorization process
import PRJNAME.lib.facebook as facebook
import simplejson
from pylons import config
class AccountController(BaseController):
def login(self):
params = {
'client_id':config['facebook.appid'],
'scope' : 'offline_access,publish_stream,email', #permissions needed by the app
'redirect_uri' : 'http://'+request.environ['HTTP_HOST']+'/account/auth'
}
keys = params.keys()[:]
keys.sort()
q_str = unicode()
for name in keys:
q_str+= ("&%s=%s" % (name,params[name]))
c.login_url = 'https://graph.facebook.com/oauth/authorize?' + q_str
return render('/website/login.html')
login.html
Login with Facebook
Add a function on helpers.py
This function will create our access_token from our code request params
import urllib
import json
def getAccessTokenFromCode(applicationId, applicationSecret, code,redirect_uri):
q_str = unicode()
params = {
'client_id':applicationId,
'client_secret':applicationSecret,
'code':code,
'redirect_uri':'http://'+request.environ['HTTP_HOST']+redirect_uri
}
keys = params.keys()[:]
keys.sort()
for name in keys:
q_str+= ("&%s=%s" % (name, params[name]))
url = 'https://graph.facebook.com/oauth/access_token?'+ q_str
response = urllib.urlopen(url).read()
result = response.split('=')[-1]
if result:
return result
Create an auth view on account controller
I do this because in the link button there is an argument called redirect_uri that points to http://ww.example.com/account/auth.
from PRJNAME.lib.helpers import getAccessTokenFromCode
from pylons import config
def auth(self):
if request.params.has_key('code'):
access_token = getAccessTokenFromCode(
config['facebook.appid'],
config['facebook.secret'],
request.params.get('code'),
redirect_uri='/account/auth'
)
graph = facebook.GraphAPI(access_token)
#grab the user data
fbdata = graph.get_object("me")
#query the db to check if user is already authorized
q = Session.query(model.Social)
user = q.filter_by(oauth_id=fbdata['id']).first()
if user:
# you can redirect to a dashboard
return 'already in db and authorized'
else:
#insert user data to db
fb = model.Social()
fb.oauth_provider = 'Facebook'
fb.oauth_id = fbdata['id']
fb.username = fbdata['name']
fb.access_token = access_token
Session.add(fb)
Session.commit()
# redirect to dashboard page
And that’s pretty much it.