In my previous post, I talked about the app-id/secret-id pair you get when you register your app to Facebook. The documentation provided by Facebook, however, is a little bit unclear about the usage model of this pair under various SDKs. In this post, I am going to write some tips for App Engine developers who are building Facebook applications using this app-id/secret-id pair.
In a nut shell,
(1) It is possible to build your application only with JavaScript SDK. In this case, you don't need a secret key to access Facebook API.
(2) This JavaScript-only above approach is fine for client-only application (such as a small widget application that presents Facebook news feed for the user), but not appropriate if you want to use Facebook API as the authentication/identification mechanism to access your database (such as per-user storage).
(3) The best approach is a hybrid application, which uses JavaScript API for log-in and various non-critical API calls (such as fetching the list of friends to present it to the user), but uses Python SDK for authentication and some critical API calls.
I built fruence.com with this hybrid architecture. Here are some code from it:
main.js (client-side):
window.fbAsyncInit = function() {
SNBinder.get('/api/appid', null, true, function(result, data) {
FB.init({appId: result.appId, status: true, cookie: true,
xfbml: true});
FB.Event.subscribe('auth.login', function(response) {
main.init();
});
FB.Event.subscribe('auth.logout', function(response) {
main.login();
});
main.init();
});
};
SNBinder.get is a wrapper of HTTP-GET and fetches the app-id by accessing /api/appid, then calls FB.init() to initialize the API. Notice that you don't need the secret-key in this case, and you don't want to (otherwise, it is no longer a secret).
When the user clicks the log-in button (provided by Facebook) and authorizes the access to the app (this UI will be provided by Facebook as well), the application receives the 'auth.login' event.
Then (within the main.init()), the application accesses '/api/user' with a cookie attached by Facebook API, which will execute the following code on the server side.
gdispatch.route(lambda: ('/api/user', ApiUserHandler))
class ApiUserHandler(webapp.RequestHandler):
@login_required
def post(self):
self.response.out.write('{"success":true, "result":%s}' % self.current_user.json)
The login-required decorator performs the server-side authentication.
def login_required(original_func):
def decorated_func(rh, **kw):
if User.current_user(rh):
return original_func(rh, **kw)
else:
return rh.response.out.write('{"success":false, "login_required":true}')
return decorated_func
User.current_user is defined as follows.
class User(db.Model):
....
@classmethod
def current_user(cls, rh):
if not hasattr(rh, "current_user"):
rh.current_user = None
(id, secret) = cls.facebook_ids(rh)
cookie = facebook.get_user_from_cookie(rh.request.cookies, id, secret)
if cookie:
key_name = "fb:"+cookie["uid"]
user = cls.get_by_id(key_name)
if not user:
graph = facebook.GraphAPI(cookie["access_token"])
profile = graph.get_object("me")
user = cls(key_name=str(key_name),
name=profile["name"],
profile_url=profile["link"],
access_token=cookie["access_token"],
cached_logs=[])
user.put()
else:
if user.access_token != cookie["access_token"]:
user.access_token = cookie["access_token"]
user.put()
rh.current_user = user
return rh.current_user
Notice that you need to give the secret-id to Facebook API (facebook.get_user_from_cookie) in this case, but your secret-id is secure because this code is on the server side.
Do you have any plams t eelease a Wndows version of your cbr viewer?
Thanks
Marc
Posted by: Marc | January 12, 2011 at 07:52 AM
Great post. Quick question, because you mention "authentication/identification mechanism to access your database (such as per-user storage)", are you using https://github.com/dound/gae-sessions or some similar session functionality to keep track of the logged in Facebook user. If so, how are you doing this? Thanks.
Posted by: Alex | January 12, 2011 at 07:31 PM
Hi,
An online form was completed here:
http://gosunwise.com/?url=satoshi.blogs.com&id=EAB001
requesting the information provided in this email some time ago, but a contact name was not given. I kindly ask that you forward this to your business owner.
SunWise Capital gives business loans of up to $250,000 or More without collateral requirements, assets or personal guarantees. With our simple Free single-page application you can find out exactly how much your business can obtain.
Our loans are also non-restrictive, which means once the loan is issued to you, you may spend it in ANY WAY your business requires. We DO NOT perform any credit checks, and applying for a loan will not be reported to the credit bureaus as an inquiry. If your practice has been in business for at least a year, the likelihood that you will receive at least 100k With No Personal Guarantee is 98%!
Click Here To Fill Out a Free 1 Page Application:
http://gosunwise.com/?url=satoshi.blogs.com&id=EAB001
*A credit check will NOT be placed on your credit report if you are declined for the loan. No one will know you applied for the loan since you already pre-qualify and no personal credit information is requested.
Sincerely yours
Peter Lands
Customer relations
[email protected]
http://gosunwise.com/
Posted by: Peter | October 10, 2013 at 05:54 PM
Learning notes about the piano is really really simple when compared with mastering
all of the notes in your six string. The best method is to simply do your
daily amount of practice and commit to staying with it for at least six months to one year.
Don't be hard on yourself and don't get discouraged.
Posted by: guitare | October 17, 2013 at 03:56 PM