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