2011-04-20 43 views
2

我已经创建了一个与Facebook连接到应用程序的Django应用程序。现在,当我点击Facebook登录按钮时,oauth页弹出窗口。当我给用户名n密码时,它会在没有实际将页面重定向到任何页面的情况下关闭。但是当我把FB页面放在一个新标签中时,我可以看到FB登录该用户的页面。所以登录是完美的,但我不明白到哪里给页面重定向后,它得到认证。有人可以帮我解决这个问题吗?这是我在我的设置页面中设置的方式?我无法找到选项中设置的任何回调URL。如何在登录Facebook后重定向网址?

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 

用于登录的代码: 这段代码被插入在registrationForm html页面(登录):

{% load facebookconnect %} 
{% facebook_connect_login_button %} 
{% facebook_connect_script %} 

和facebookconnect.py代码是:

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) 
+1

发布您的登录代码弹出。 – 2011-04-20 13:39:21

+0

我已经发布了我的FB登录码。你可以请现在检查吗? – 2011-04-21 04:28:26

回答

5

如果你说oauth只是弹出窗口,我想你正在使用JS的Facebook库。我会去简单的OAuth的重定向方式,采用了以下内容:

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") 

哪里self.app_id是你的Facebook应用程序ID。 其中self.redirect_uri是登录后用户将被重定向的网址。 self.req_perms是self.req_perms构建的,self.req_perms是所需权限的数组。

之后,他们的用户会被重定向在邮寄的访问令牌REDIRECT_URI“signed_request”参数,你可以用下面的函数将其解码:

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 

例子:

sigreq =request.POST.get('signed_request', None) 
user_id,access_token = load_signed_request(sigreq) 

再次,您将需要self.app_secret和以下功能:

@staticmethod 
    def base64_url_decode(data): 
      data = data.encode(u'ascii') 
      data += '=' * (4 - (len(data) % 4)) 
      return base64.urlsafe_b64decode(data) 

我有很多FB JS登录和身份验证的麻烦,特别是在不同的浏览器,这种方式是我可以找到更强大的方式:)

Btw如果你想我的facebook.py文件,我可以把它放在网上地方......它甚至有一个@fbsig_required和@fbsig_redirect视图装饰...

哦,这里也有我的进口:

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 
+0

非常感谢您的帮助矮人..我会检查与此并回复回来..你还可以为我分享你的facebook.py文件? – 2011-04-21 04:14:35

+0

嗨,谢谢你的好话:) – dwarfy 2011-04-21 08:57:59

+0

你可以找到我的facebook.py文件[在这里bitbucket](https://bitbucket.org/dwarfy/my-facebook-py/src) – dwarfy 2011-04-21 08:58:27