I have created a django application with a Facebook connect to the application. Now when i click on the Facebook login button, the oauth page pop ups. When i give the username n password, it gets closed without actually redirecting the page to any page. But when i took FB page in a new tab, i could see the FB logged in page of that user. So the login is working perfect, but i dont understand where to give the page redirection after it gets authenticated. Can somebody help me to solve this. This is how i set in my settings page ? I couldnt find any callback url to be set in the opti开发者_JAVA技巧ons.
App ID
xxxx
API Key
xxxx
App Secret
xxx
Site URL
http://localhost:8080/redirect_url/
Site Domain
localhost
Canvas Page
http://apps.facebook.com/registrationforms/
Canvas URL
http://apps.facebook.com/registrationforms/
Secure Canvas URL
Canvas FBML/iframe
iframe
The code for login : This piece of code is inserted in the registrationForm html page(login) :
{% load facebookconnect %}
{% facebook_connect_login_button %}
{% facebook_connect_script %}
and the facebookconnect.py code is :
from django import template
from django.conf import settings
from django.core.urlresolvers import reverse
register = template.Library()
class FacebookScriptNode(template.Node):
def render(self, context):
return """
<script src="http://static.ak.connect.facebook.com/js/api_lib/v0.4/FeatureLoader.js.php" type="text/javascript"></script>
<script type="text/javascript"> FB.init("%s", "%s");
function facebook_onlogin() {
var uid = FB.Facebook.apiClient.get_session().uid;
var session_key = FB.Facebook.apiClient.get_session().session_key;
var expires = FB.Facebook.apiClient.get_session().expires;
var secret = FB.Facebook.apiClient.get_session().secret;
var sig = FB.Facebook.apiClient.get_session().sig;
fb_connect_ajax(expires, session_key, secret, uid, sig);
}
function fb_connect_ajax(expires, session_key, ss, user, sig) {
var post_string = 'expires=' + expires;
post_string = post_string + '&session_key=' + session_key;
post_string = post_string + '&ss=' + ss;
post_string = post_string + '&user=' + user;
post_string = post_string + '&sig=' + sig;
$.ajax({
type: "POST",
url: "%s",
data: post_string,
success: function(msg) {
window.location = '%s'; //.reload()
}
});
}
</script>
""" % (settings.FACEBOOK_API_KEY, reverse('xd_receiver'), reverse('facebook_connect_ajax'), settings.LOGIN_REDIRECT_URL)
def facebook_connect_script(parser, token): return FacebookScriptNode()
register.tag(facebook_connect_script)
class FacebookLoginNode(template.Node):
def render(self, context):
return "<fb:login-button onlogin='facebook_onlogin();'></fb:login-button>"
#return "<fb:login-button onclick="openPopup('https://graph.facebook.com/oauth/authorize?client_id=a0acfd122e64fc21cfa34d47369f0c97&redirect_uri=http://mysite.com/mypage&display=popup');"></fb:login-button>"
def facebook_connect_login_button(parser, token): return FacebookLoginNode()
register.tag(facebook_connect_login_button)
I suppose you are using the JS Facebook library if you say that the oauth just pop ups. I would go the simpler oauth redirect way, using a the following :
def build_authentication_redirect(self):
args = {}
args["client_id"]=self.app_id
args["redirect_uri"]=self.redirect_uri
args["scope"]=",".join(self.req_perms)
redirect_url = "https://www.facebook.com/dialog/oauth?"+urllib.urlencode(args)
redirect_code = """
<script type="text/javascript">
top.location.href='%s';
</script>
""" % redirect_url;
return HttpResponse(redirect_code,mimetype="text/html")
Where self.app_id is your facebook app id. Where self.redirect_uri is the url the user will be redirected after login. Where self.scope is built from self.req_perms which is an array of the required permissions.
After that they user will be redirected to redirect_uri with the access token in post 'signed_request' parameter, you can use the following function to decode it :
def load_signed_request(self, signed_request):
"""Load the user state from a signed_request value"""
sig, payload = signed_request.split(u'.', 1)
sig = self.base64_url_decode(sig)
data = json.loads(self.base64_url_decode(payload))
expected_sig = hmac.new(self.app_secret, msg=payload, digestmod=hashlib.sha256).digest()
# allow the signed_request to function for upto 1 day
if sig == expected_sig and data[u'issued_at'] > (time.time() - 86400):
return data.get(u'user_id'), data.get(u'oauth_token')
else:
return None,None
Example :
sigreq =request.POST.get('signed_request', None)
user_id,access_token = load_signed_request(sigreq)
Again you will need self.app_secret and the following function :
@staticmethod
def base64_url_decode(data):
data = data.encode(u'ascii')
data += '=' * (4 - (len(data) % 4))
return base64.urlsafe_b64decode(data)
I had a lot of trouble with FB JS login and auth, especially on different browsers, this way is the more robust way I could find :)
Btw If you want my facebook.py file I can put it available online somewhere ... It even has a @fbsig_required and @fbsig_redirect view decorators ...
Oh Also here are my imports :
import cgi
import hashlib
import time
import urllib
import base64
import datetime
import hmac
from django.conf import settings
from django.http import HttpResponseRedirect,HttpResponse,HttpResponseNotFound
Check this, may this will give you some idea to make that work:
https://stackoverflow.com/questions/2690723/facebook-graph-api-and-django/5539531#5539531
精彩评论