Skip to content

Instantly share code, notes, and snippets.

@geschke
Created May 10, 2010 21:15
Show Gist options
  • Save geschke/396557 to your computer and use it in GitHub Desktop.
Save geschke/396557 to your computer and use it in GitHub Desktop.
Django Middleware for Facebook integration. Slightly modified to work with newer versions of Python Facebook SDK from https://github.com/pythonforfacebook/facebook-sdk
# Facebook Connect Middleware with new Facebook Python SDK from https://github.com/pythonforfacebook/facebook-sdk and Graph API
#
# based on http://www.djangosnippets.org/snippets/1252/
#
from django.contrib.auth import authenticate, login, logout, get_user
from django.contrib.auth.models import User
from django.conf import settings
from kuerbisorg.comcore.models import ComUser, COUNTRY_CHOICES, ACTIVE_CHOICES
import hashlib
import facebook
PROBLEM_ERROR = 'There was a problem. Try again later.'
ACCOUNT_DISABLED_ERROR = 'Your account is not active.'
ACCOUNT_PROBLEM_ERROR = 'There is a problem with your account.'
class FacebookConnectMiddleware(object):
delete_fb_cookies = False
facebook_user_is_authenticated = False
def process_request(self,request):
try:
# Set the facebook message to empty. This message can be used to display info from the middleware on a Web page.
request.facebook_message = None
# Don't bother trying FB Connect login if the user is already logged in
if not request.user.is_authenticated():
# FB Connect will set a cookie with a key == 'fbm_' + Application ID if the user has been authenticated
if "fbm_" + settings.FB_APP_ID in request.COOKIES:
current_user = facebook.get_user_from_cookie(request.COOKIES, settings.FB_APP_ID, settings.FB_API_SECRET)
if current_user:
graph = facebook.GraphAPI(current_user["access_token"])
profile = graph.get_object("me")
try:
# Try to get Django account corresponding to friend
# Authenticate then login (or display disabled error message)
django_user = User.objects.get(username="fb_" + profile['id'])
user = authenticate(username="fb_" + profile['id'],
password=hashlib.md5("fb_" + profile['id'] + settings.SECRET_KEY).hexdigest())
if user is not None:
if user.is_active:
login(request, user)
self.facebook_user_is_authenticated = True
else:
request.facebook_message = ACCOUNT_DISABLED_ERROR
self.delete_fb_cookies = True
else:
request.facebook_message = ACCOUNT_PROBLEM_ERROR
self.delete_fb_cookies = True
except User.DoesNotExist:
# There is no Django account for this Facebook user.
# Create one, then log the user in.
# Create user
user = User.objects.create_user("fb_" + profile['id'], '',
hashlib.md5("fb_" + profile['id'] +
settings.SECRET_KEY).hexdigest())
user.first_name = profile['first_name']
user.last_name = profile['last_name']
user.save()
comUser = ComUser(user=user,
active='a',
source='FB',
country='__' # todo: get from locale
)
regToken = comUser.createToken()
comUser.save()
# Authenticate and log in (or display disabled error message)
user = authenticate(username="fb_" + profile['id'],
password=hashlib.md5("fb_" + profile['id'] + settings.SECRET_KEY).hexdigest())
if user is not None:
if user.is_active:
login(request, user)
self.facebook_user_is_authenticated = True
else:
request.facebook_message = ACCOUNT_DISABLED_ERROR
self.delete_fb_cookies = True
else:
request.facebook_message = ACCOUNT_PROBLEM_ERROR
self.delete_fb_cookies = True
else:
logout(request)
self.delete_fb_cookies = True
else:
get_user(request)
self.delete_fb_cookies = True
# Logged in
else:
comUser = ComUser.objects.get(user=request.user)
if comUser.source == 'FB': # check successful facebook login. If user is logged per site authentication only, just pass.
# FB Connect user?
if "fbsr_" + settings.FB_APP_ID in request.COOKIES:
# IP hash cookie set
if 'fb_ip' in request.COOKIES:
real_ip = self.get_real_ip(request)
# If IP hash cookie is NOT correct... otherwise: pass
if request.COOKIES['fb_ip'] != hashlib.md5(real_ip + settings.FB_API_SECRET + settings.SECRET_KEY).hexdigest():
logout(request)
self.delete_fb_cookies = True
# FB Connect user without hash cookie set
else:
logout(request)
self.delete_fb_cookies = True
else:
logout(request)
self.delete_fb_cookies = True
# Something else happened. Make sure user doesn't have site access until problem is fixed.
except:
request.facebook_message = PROBLEM_ERROR
logout(request)
self.delete_fb_cookies = True
def process_response(self, request, response):
# Delete FB Connect cookies
# FB Connect JavaScript may add them back, but this will ensure they're deleted if they should be
if self.delete_fb_cookies is True:
response.delete_cookie("fbm_" + settings.FB_APP_ID)
self.delete_fb_cookies = False
if self.facebook_user_is_authenticated is True:
real_ip = self.get_real_ip(request)
response.set_cookie('fb_ip', hashlib.md5(real_ip + settings.FB_API_SECRET + settings.SECRET_KEY).hexdigest())
# process_response() must always return a HttpResponse
return response
def get_real_ip(self, request):
try:
real_ip = request.META['HTTP_X_FORWARDED_FOR']
except KeyError:
real_ip = request.META['REMOTE_ADDR']
return real_ip
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment