giovedì 28 aprile 2011

The very basics of Facebook apps on Django

Working on a facebook app i discovered that:

  • Pyfacebook doesn't work anymore.
  • Other projects are far too complicated (or maybe i'm just lazy) to suit to my app.
  • The majority of the tutorials i could find on the internet were largely out of date.

So, here's all you need to simply retrieve the user data you desire from facebook using django.

All you need is facebook python sdk.

Thanks to Sulil Arora for sharing this snippet, it helped a lot.

Just create a django app, create a view using the following code and set it as your facebook app's canvas page.

You can find a project using this piece of code here




import base64
from django.http import HttpResponse, HttpResponseRedirect
from django.views.decorators.csrf import csrf_exempt
from django.utils import simplejson
import facebook

APP_ID = 'my_app_id'

### CHECK SIGNED REQUEST
import hmac
import hashlib
APP_SECRET = "my_app_secret"

@csrf_exempt #or post requests will be blocked
def canvas(request):
#Facebook sends base64 encoded data via POST

sr = request.POST['signed_request']
#We check the signature and retrieve basic user data
data = parse_signed_request(sr,APP_SECRET)
if data is None:
# Algorithm is unknown or the signed request
#doesn't come from Facebook. You should handle this.
return HttpResponse('ERROR')

user_id = data.get('user_id',False)
oauth_token = data.get('oauth_token',False)
# If we're to retrieve his/her data
# we'll find user_id and oauth_token in data.
# If we're not we need to redirect the user to facebook
# auth dialog

if not user_id or not oauth_token:
# Need authorization for more data
# redirect to Facebook oauth dialog
# using a script (see Facebook docs)
redirect_url = "https://www.facebook.com/dialog/oauth?"+\
"client_id=%s&redirect_uri=%s"\
% (APP_ID,'http.//www.example.com/canvas/')

return HttpResponse(
"<script> top.location.href='%s' </script>"\
% redirect_url
)

f = facebook.GraphAPI(oauth_token)
user_data = f.get_object(user_id)

### Use user's data as needed

return HttpResponse('OK')

def base64_url_decode(inp):
"""
Cleans a base64 encoded string and returns
it decoded
"""
padding_factor = (4 - len(inp) % 4) % 4
inp += "="*padding_factor
return base64.b64decode(
unicode(inp).translate(
dict(zip(
map(ord, u'-_'),
u'+/'
))
)
)

def parse_signed_request(signed_request, secret):
"""
Check if the received signed_request is really coming
from Facebook using your app secret key.
Returns a dict containing facebook data or None if it fails.
"""
l = signed_request.split('.', 2)
encoded_sig = l[0]
payload = l[1]

sig = base64_url_decode(encoded_sig)
data = simplejson.loads(base64_url_decode(payload))

if data.get('algorithm').upper() != 'HMAC-SHA256':
return None

else:
expected_sig = hmac.new(secret,
msg=payload,
digestmod=hashlib.sha256).digest()

if sig != expected_sig:
return None
else:
return data

Nessun commento:

Posta un commento