通过Iphone Native Client使用Google App Engine进行身份验证

时间:2011-01-19 00:45:33

标签: iphone google-app-engine authentication facebook cocos2d-iphone

我想制作一款Iphone游戏,用户可以使用自己的Facebook凭据登录,并通过在Google App Engine上运行的服务器进行身份验证。我已经让Facebook连接iPhone和Google App Engine。然而,似乎Facebook连接iPhone只能通过Facebook的服务器验证您,并允许您从Facebook访问Facebook Api。

我想这样做的原因是,我可以在GAE上存储与用户帐户关联的额外用户数据,但也可以使用他们的Facebook凭据登录。

是否可以使用iPhone本机客户端使用其Facebook凭据对用户进行身份验证,但是可以通过我的服务器进行身份验证?看起来像iPhone的Farmville就是这样的。

如何做到这一点?

2 个答案:

答案 0 :(得分:1)

这可以通过GAE应用程序上的中间Facebook API代理实现。

通过一些代码略读这一点,我将客户提供的auth.getSessionauth_token称为经典API generate_session_secret,当然format是{ {1}}。

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

基本上发生的是客户端登录,获取身份验证令牌,将其发布到中间代理,然后请求Facebook使用该令牌进行会话,并将其返回给Connect客户端。

答案 1 :(得分: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()