Facebook接入方法

一,准备好开发者账号

开发者账号怎么设置我就不说了。和人人平台基本一样。很多平台都这样。

在得到 Application ID (App ID/ API Key) 和 Application secret(App Secret) 之后,记录好这两项,准备做接入。当然,还要牢记你自己的Canvas Page。

 

好,下一步。在开发者账号创建了这个应用之后,你可以访问一下Canves Page。

例如:http://apps.facebook.com/xxxapptest/

看一下效果。正常的话,可以看到连接到你的网站主页上了。

二,认证与授权

     Facebook平台的身份验证和授权是基于OAuth 2.0协议的( OAuth 2.0 protocol )。

     用户在登录之后可以有两种方式做身份验证和授权:服务器端(server-side)和客户端(client-side)。无论用哪种,都需要遵守下面的三步:用户身份验证(user authentication),用户授权 (app authorization) ,和 应用身份验证(app authentication)。 用户身份验证是确认用户身份;用户授权是让用户确认将会提供给应用什么样的个人数据和内容;应用身份验证是确认用户把他们的资料给的是你的应用,而不是别人。一旦这些步骤完成了,你的应用将会获得到一个用户访问令牌( user access token ),这样你的应用就能获取到用户的信息,并且可以获取到用户的活动和行为了。

----------------------------------------------------------------------------------------------

1. 用户授权 (user authorization)

下边我只说服务器端的认证授权流程。

获取用户基本信息的授权方式

用户第一次登陆,facebook把用户跳转到我们的应用服务器,那么我们要调用这样一个url:

https://www.facebook.com/dialog/oauth?client_id=YOUR_APP_ID&redirect_uri=YOUR_URL

 

其实就是调用facebook的标准认证对话框(OAuth Dialog)。如果用户点击确认了,注意,这个授权,应用只能是获取到用户的基本信息的,也就是facebook上用户的公共信息。例如ID,主页,用户的名字。

获取用户的其他信息的授权方式:

如果想获取到用户的其他信息,就必须明确的告诉用户,你的应用需要哪些用户的信息,像下面这样:

https://www.facebook.com/dialog/oauth?client_id=YOUR_APP_ID&redirect_uri=YOUR_URL&scope=email,read_stream

 

scope参数里面,指定了你的应用想要获取的用户信息。

 

用户同意授权

假如用户点击了同意(Allow),那么你的应用就会被用户授权了。授权对话框( OAuth Dialog)将会带着认证码(authorization code)参数跳转(via HTTP 302)到你的服务器的url。我查看了整个授权后的request,发现,facebook把认证码放在了GET里,其他的信息在POST里。GET里面会有一个code参数,好长一串,这个就是授权码。有了这个code,我们就可以进行下一步应用身份验证了。

----------------------------------------------------------------------------------------------

2. 应用身份验证(app authentication)

为了验证你的应用(app),你必须把上面得到的授权码(authorization code)和你的应用密钥(App Secret)传给 Graph API的令牌终点( token endpoint):

https://graph.facebook.com/oauth/access_token

格式是这样的:

https://graph.facebook.com/oauth/access_token?
client_id=YOUR_APP_ID&redirect_uri=YOUR_URL&
client_secret=YOUR_APP_SECRET&code=THE_CODE_FROM_ABOVE

 

如果你的应用成功的通过了认证,并且你的用户的授权码也是合法的,那么授权服务器将会返回访问令牌(access token)。

 

 

----------------------------------------------------------------------------------------------

现在我们来看一下,网站接收到的facebook传来的request的POST数据:

注意,此时是在没有授权的情况下,从平台发过来的请求。

    u'fb_sig_time': [u'1310471486.9658'], 
    u'fb_sig_added': [u'0'], 
    u'fb_sig_locale': [u'zh_CN'], 
    u'fb_sig_in_iframe': [u'1'], 
    u'fb_sig_in_new_facebook': [u'1'], 
    u'fb_sig_country': [u'us'], 
    u'fb_sig': [u'6edf97802d706b84753a4a328d65b1cc'],   
    u'fb_sig_api_key': [u'6361833388ca80696ad667af7abcceee'], 
    u'fb_sig_app_id': [u'120306072668168']

好,按照facebook的规则,要想得到用户的信息,你的这个应用必须得到用户的授权(Authorization)。这个授权,就好比,用户在facebook上,确认安装你的游戏。

授权的格式,开发者文档写的很明白:

https://www.facebook.com/dialog/oauth?
     client_id=YOUR_APP_ID&redirect_uri=YOUR_CANVAS_PAGE

上面我们说的Application ID (app ID)和Canves Page在这里就能用得上了。

在浏览器中输入这个授权url,就会看到你的应用的用户授权页。

当用户点击确定授权的时候,facebook将会给我们的网站发来这样的request内容:

POST:

    u'fb_sig_time': [u'1310627493.7758'], 
    u'fb_sig_added': [u'1'], 
    u'fb_sig_locale': [u'zh_CN'], 
    u'fb_sig_in_iframe': [u'1'], 
    u'fb_sig_in_new_facebook': [u'1'], 
    u'fb_sig_profile_update_time': [u'1256108103'], 
    u'fb_sig_country': [u'us'], 
    u'fb_sig_ss': [u's2Ke_YrygH7T8aEd9Lmcrg__'], 
    u'fb_sig_user': [u'100000413372683'], 
    u'fb_sig_cookie_sig': [u'3bce4346fd8f2f62c347eae9e89ae2d8'], 
    u'fb_sig_session_key': [u'2.AQC9WncK12nGzWCn.3600.1310634000.0-100000413372683'], 
    u'fb_sig_expires': [u'1310634000'], 
    u'fb_sig': [u'af28d8df0e0ec5fbbf01ec430622278d'], 
    u'fb_sig_api_key': [u'6361833388ca80696ad667af7abcceee'], 
    u'fb_sig_app_id': [u'120306072668168']

可以看见,POST里面已经有了uid了。

 

授权(authorization)

     为了给用户创造人性化(personalize)的体验,Facebook将把用户的信息,在用户允许的情况下发送给你的应用。这些信息将通过HTTP POST里的 signed_request 参数传给你的应用。 signed_request 其实就是一个经过base64url 编码的JSON对象。所以,在你解码之前,signed_request的内容看上去就是一个用点(.)分割的长串数据。

     用户第一次访问你的应用的时候,signed_request参数只包含下面这些数据(如果你看不到数据,只看到一长串字母数字,那请先看下边的解码签名请求)。可以看到,几乎没有什么有用的用户数据:

 

NameDescription
user A JSON array containing the locale string, country string and the age object (containing the min and max numbers of the age range) for the current user.  里面只有local,county,和age 没有uid 和token!
algorithm A JSON string containing the mechanism used to sign the request.
issued_at A JSON number containing the Unix timestamp when the request was signed.

 

 

     为了获取有用的用户信息,比如用户在Facebook的ID,那么你需要得到用户的授权。官方建议是使用认证对话框(OAuth Dialog) 进行用户对应用的授权。怎么引用这个对话框,进行授权呢?其实就是在你的服务器端或者页面端,跳转到 Facebook指定的URL。这个URL规则如下:

https://www.facebook.com/dialog/oauth?client_id=YOUR_APP_ID&redirect_uri=YOUR_CANVAS_PAGE

   当跳转到这个URL的时候,就会出现facebook标准的认证对话框了。注意,上面这种规则的URL授权对话框,你的应用只能是获取到用户的基本信息的,也就是facebook上用户的公共信息。例如ID,主页,用户的名字。如果你想获取到用户的其他信息,就必须明确的告诉用户,你的应用需要获取哪些用户的信息,像下面这样:

https://www.facebook.com/dialog/oauth?client_id=YOUR_APP_ID&redirect_uri=YOUR_URL&scope=email,read_stream

注意,scope参数里面,指定了你的应用想要获取的用户信息。

     假如用户点击了同意(allow),那么用户就对应用授权了。授权后,signed_request参数将含下面这些数据。可以看到,可以得到重要的两项:用户的id,就是user_id;和oauth_token 。

 

NameDescription
user A JSON array containing the locale string, country string and the age object (containing the min and max numbers of the age range) for the current user.
algorithm A JSON string containing the mechanism used to sign the request.
issued_at A JSON number containing the Unix timestamp when the request was signed.
user_id A JSON string containing the Facebook user identifier (UID) of the current user.
oauth_token A JSON string that you can pass to the Graph API or the Legacy REST API.
expires A JSON number containing the Unix timestamp when the oauth_token expires.

 

 

解码签名请求(Decode Signed Request)

     Facebook把请求做了签名。形成了signed_request这个东西。signed_request 其实就是一个经过base64url 编码的JSON对象。直接取过来,就是一个用"."分割的字符串。我们要做的,是把点前面的字符串解码,就是验证是否是facebook的合法sig;把点后面的字符串解码,就是facebook传给你应用的具体数据data。

   具体算法python版:

    # reques就是facebook发过来的请求
    params = request.POST.copy()        
    signed_request = params.get('signed_request')
    # signed_request传到python这边, 数据结构是一个字符串型的list
    if isinstance(signed_request, list):
        signed_request = signed_request[0]
    encoded_sig, payload = signed_request.split(".", 2)

    # 余数2, 那么需要补一个=
    payload = str(payload)
    if len(payload)%3 == 2:
        payload += '='
    # 余数1, 那么需要补两个=  
    if len(payload)%3 == 1:
        payload += '=='    
    # urlsafe_b64decode() Decode string s using a URL-safe alphabet, 
    # which substitutes - instead of + and _ instead of / in the standard Base64 alphabet.
    # 得到data    
    data = simplejson.loads(base64.urlsafe_b64decode(payload))
    
    # 得到sig
    encoded_sig = str(encoded_sig)
    if len(encoded_sig)%3 == 2:
        encoded_sig += '='
    if len(encoded_sig)%3 == 1:
        encoded_sig += '==' 
    sig = base64.urlsafe_b64decode(encoded_sig)

  

获取用户信息

     经过上面的解码签名请求后,可以获取到FB的数据了。就是上面代码里的data。如果里面有'user_id' 那么就说明,uid和oauth_toke都有了。请注意,如果您用的是国内服务器,是不可以直接调用facebook API接口的。

    if 'user_id' in data:
        uid = data['user_id']
        params_dic = {}
        params_dic['uid'] = uid
        params_dic['oauth_token'] = data['oauth_token']

  

有了这uid和oauth_toke,我们就可以获取其他的用户信息了。下面是获取几个重要接入属性的方法。如果不明白为什么这么写,可以参考facebook开发文档。

   用户昵称

graph_url = "https://graph.facebook.com/%s" % uid
facebook_usr_info = simplejson.loads( urllib2.urlopen(graph_url).read() )
name = facebook_usr_info['name']

   好友列表:

graph_url = "https://graph.facebook.com/me/friends?access_token=%s" % oauth_token
f_dic = simplejson.loads(urllib2.urlopen(graph_url).read())
friends_ids = f_dic['data']

 头像:

        headurl = 'http://graph.facebook.com/' + uid + '/picture' 

 

posted @ 2013-07-02 11:15  编程狂热者  阅读(8092)  评论(0编辑  收藏  举报