2

我想創建一個Iphone遊戲,用戶可以使用他們的Facebook憑據登錄並使用在Google App Engine上運行的服務器進行身份驗證。我已經獲得了Facebook連接iPhone和Google App Engine的工作。然而,Facebook的Facebook連接似乎只能通過Facebook的服務器進行身份驗證,並允許您從Facebook訪問Facebook Api。使用Google App Engine從Iphone Native Client進行身份驗證

我想這樣做的原因是,我可以在GAE上存儲與用戶帳戶關聯的額外用戶數據,但也讓他們用他們的Facebook憑證登錄。

是否可以使用iPhone本機客戶端使用其Facebook身份驗證用戶身份,但通過我的服務器進行身份驗證?對於iPhone來說,Farmville似乎就是這樣做的。

任何想法如何完成?

回答

1

這可以通過GAE應用程序上的中間Facebook API代理實現。

一些代碼,略讀我做這個,我稱之爲經典API auth.getSessionauth_token和客戶端提供generate_session_secret,當然format的是XML

http://developers.facebook.com/docs/reference/rest/auth.getSession/

本質上發生的事情是在客戶端登錄,獲取認證令牌,職位,以中間代理,然後要求Facebook上的會話中使用該令牌,即返回給客戶端連接。

+0

那麼一旦用戶在服務器上有一個會話,你如何驗證所有未來對服務器的請求呢? – 2013-02-22 17:53:18

0

這是一個GAE代理,您可以使用Facebook連接從iPhone應用程序調用。

調用它的facebookProxy或任何和GAE上添加一個URL處理程序。

調用它使用的iPhone應用程序中:

session = [FBSession sessionForApplication:myApiKey getSessionProxy:@"http://yourApp.appspot.com/facebookProxy" delegate:self];

下面是代理的Python代碼。我使用單獨的常量文件來存儲Facebook應用程序密鑰,因此您需要更改以使用它。

import cgi 
import hashlib 
import httplib 
import urllib 
import logging 
from google.appengine.ext.webapp.util import run_wsgi_app 
from google.appengine.ext import webapp 
from google.appengine.api import users 
import Constants 

FB_API_HOST="api.facebook.com" 
FB_API_PATH="/restserver.php" 

def facebook_signature(paramsDict): 
    """Compute the signature of a Facebook request""" 
    sorted = paramsDict.items() 
    sorted.sort() 

    trace = ''.join(["%s=%s" % x for x in sorted]) 
    trace += Constants.FB_API_SECRET() 

    md5 = hashlib.md5() 
    md5.update(trace) 
    return md5.hexdigest() 

def get_fb_session(auth_token): 
    """Request a Facebook session using the given auth_token""" 
    params={ 
      "api_key":Constants.FB_API_KEY, 
      "v":"1.0", 
      "auth_token":auth_token, 
      "generate_session_secret":"1", 
      "method":"auth.getSession", 
    } 
    params["sig"] = facebook_signature(params) 

    encoded_params = urllib.urlencode(params) 
    headers = { 
      "Content-type":"application/x-www-form-urlencoded", 
    } 

    conn = httplib.HTTPConnection(FB_API_HOST) 
    conn.request("POST", FB_API_PATH, encoded_params, headers) 
    logging.debug("%s" % encoded_params) 
    return conn.getresponse() 

class FacebookSessionProxy(webapp.RequestHandler): 
    def get(self): 
     response = self.response 
     auth_token = self.request.get('auth_token') 
     logging.debug("AUTH TOKEN: %s" % auth_token) 
     if len(auth_token) == 0: 
      response.set_status(httplib.BAD_REQUEST) 
      response.out.write("Facebook login error: no auth_token given.") 
      return 
     fbResponse = get_fb_session(auth_token) 
     response.out.write(fbResponse.read()) 
     response.set_status(fbResponse.status, fbResponse.reason) 
     response.headers['Content-Type'] = fbResponse.getheader('content-type') 

# The End 

application = webapp.WSGIApplication(
            [ 
             ('/facebookproxy', FacebookSessionProxy), 
            ], 
            debug=True) 

def main(): 
    logging.getLogger().setLevel(logging.DEBUG) 
    run_wsgi_app(application) 

if __name__ == "__main__": 
    main() 
相關問題