Slow load facebook canvas app when click on links (if target top) - facebook

Situation: I am developing a facebook canvas app. Facebook is sending my sever a POST request with the signed_request each time that a page is render. Inside my app I have all my links with target="_top" because if I don't, facebook send my server a common GET without the signed request. So I cann't check the user info.
Problem: It is too slow! even if I am testing it in local, each click that I press takes 1 sec to render and my canvas becomes completely white and then the info is shown, It will be a bad user experience.
My tests: If I remove the target=_top and I point all my links' href to my server without the app.facebook.com/whatever, it loads very quickly.
My doubts: Is there any security issue with this? If I point all the links to my server (no apps.facebook.com) I can not check the signed request, I will only check it in the main page..
Any advice? any tutorial? Do I have any misundestanding of this? (It is my first facebook app)

Have you read the Server-Side Authentication tutorial?
You're doing it wrong.
Once the users lands in your app you should keep all links in the same frame, loading the entire window along with facebook is completely redundant.
What you should do:
When you get the POST with the signed request, decode it and check if the user is authenticated, if he is persist the data (token and such) somewhere (session, db, cache).
If he is not authenticated send him to the auth dialog as noted in the tutorial, when he gets back exchange the code you get (in GET) for the token (also shown in the tutorial), then redirect him to http(s)://apps.facebook.com/YOUR_APP and you'll be posted with the authenticated signed request, save it, etc..
Since you persist the data, in every request that is not POST or don't include the signed_request check your persistency choice for the data, and use it.
There should be only two times where facebook sends you the request, once it is POST when your canvas is loaded, the 2nd is when the user returns from the authentication dialog, in which you either get the code parameter or error in case the user declined the authentication.
Other requests should be from your app (inside the iframe) into the app servers.

JDL,
I believe you are querying the graph API at each request (and that's why you always need the signed_request). Is this right?
The graph API is pretty slow (~ 1 second/query) and you should use only when necessary. For example, when you first receive the access_token you should save it in your session and query the graph API to retrieve the respective facebook user info. But then you should put the info you need about this user in your session and only refresh it (using the graph API) when the signed_request access token is different from the one you have saved in your session.
The behavior of adding _top to the target of your links is ok and a good practice within facebook canvas.

Related

Dertermine if user is logged in to Facebook w/o using Facebook api

I'm serving a list of events to my clients’ website. They include it via php/curl (rather than iFrame), so they can fully customize the CSS.
However, this means that I can’t use the Facebook API to find out wether a visitor of my client’s page is logged in to FB: The FB-API call needs to be signed by an application and shall only be called from the domain the application is associated with. (That would be my server’s domain, but the requests are coming from my client’s page.)
Back in the old days, accessing a user profile on FB would issue a 404 error, if not logged in.
<script type="text/javascript" src="https://www.facebook.com/pianojoe" onload="enable_social_links()" onerror="not_logged_in_to_facebook()" async="async"></script>
That was convenient, but FB took care :-/ of it.
I want to show FB-links for the events in my calendar only if the page visitor is logged in to Facebook.
My question: How do I find out if a page visitor is logged in to Facebook if I can’t determine the domain of the referring page beforehand, and therefore not use the Facebook API?
The Facebook PHP SDK has a (relatively new) method called getLoginStatusUrl.
It creates a simple URL that you redirect the user’s browser to, which takes them to Facebook, where his login status is checked, and then redirects them back to one of three different URLs of your app, that you can specify.
ok_session is the one that you would be mainly interested in here: “URL to return if the user is logged in to Facebook.”
(The other two are no_user for when the user is logged out of Facebook, and no_session for when Facebook themselves can’t figure out the user’s status, because there’s no user-specific FB cookies whatsoever set in their browser.)
So you could set ok_session to an URL of your application with an additional GET parameter like ?logged_into_fb=true (the other two options, if not specified explicitly, will then only redirect back to your app’s base URL) – and that way, when the user is redirected back to your app with that parameter, you know they are currently logged into Facebook.
Whether or not you are actually using the FB PHP SDK does not really matter – by looking at the source code of the method it’s relatively easy to figure out how the actual URL is build, so you could easily adapt that and use it without the SDK as well.

Facebook user authentication on app server

All I want is to find at least one working solution for this simple thing.
I want to determine what facebook user making request to my FB canvas application. I also want the mechanism to take into account cases when user logs off or re-logs on.
I've really broken my head on that :(
Ways i've already tried:
1) Getting and parsing signed_request param while user's initial request to the application. Cons: the canvas main page is the only place to get it. I never know what user is doing next actions.
2) Using fbsr cookie. Cons: sometimes i get error when trying to exchange cookie's code to user's access token. I still cant reproduce it, it just occurs. Btw, does it work at your?
3) Handling every get/post request at client side and adding user's access token being retrieved by JS SDK to the request. Doesnt seem to be a good way.
Well, that's it. What im doing wrong? Will be thankfull a lot for any working solution.
1) Getting and parsing signed_request param while user's initial request to the application. Cons: the canvas main page is the only place to get it. I never know what user is doing next actions.
Well then just put the parsed signed request into the session …
That’s what I usually do – every time Facebook::getSignedRequest results in something other then null, I write it into my session (so I don’t miss if it gets updated, f.e. by the user liking the page).

signed_request is going away inside Facebook App

I just want to ask a question about Facebook "signed_request" thing.
I'm using Zend Framework for my app.
The thing is; when user first authorizes my app OR enters the app from apps.facebook.com/my_app/ URL, I'm successfully retrieving signed_request.
Actually, I'm retrieving it from apps.facebook.com/my_app/index.php (Thanks to this question)
OK, app has been started, I received signed request, stored it in user session. However, when user clicks anywhere in my app, $facebook object is created again but this time, it has no signed_request.
According to this topic on Codeplex, I can expect that signed_request will come in this second request of user:
Instead of using the cookie you should use the signed request value
that Facebook POSTS to your page on each request.
On the other hand, Facebook documentation says:
A signed_request is passed to Apps on Facebook.com when they are
loaded into the Facebook environment
Now, does Facebook sends this request on each call or is there a technical problem on my app? Could it be an IFrame issue? When user click "categories", page is loading in same iframe and URL on address bar does not change.
I think it's basically a difference of definition on what "each request" means. Facebook will POST signed_request to your page only when the containing iframe is first constructed, i.e. when the user goes directly to apps.facebook.com/your_app/somepage.php as their browser location. If the user then follows a "normal" link on your page that results in only a reload of the iframe and not the entire page, no signed_request will be sent. If it helps to think of it this way, signed_request is sent when the user first loads your app, but not on each subsequent request. The reason there is some confusion about this is that many coders have taken a hackish shortcut by making all their links use target=_top and pointing them at apps.facebook.com/your_app/yourpage.php rather than www.yourdomain.com/yourpage.php. Since that results in the entire page being re-constructed each time, it does indeed have the effect of sending signed_request with each page fetch. But in normal (and recommended) operation, you'll need to count on signed_request only being sent once.

Facebook Graph API server side authentication (no client side)

So I have stored the "access_token" and marked it as "offline_access". All that is fine. Now, what I am trying to do is: I want a PHP page to "refresh"/be executed every minute, and then use that token that I stored (which I want to change at anytime manually, say from a field in the database) and then change the status of the user. Say I have the tokens for 3 of my facebook accounts.
I know how to post and all that, but when I try it without a session, it is telling me I need to create a session to do it. However, this is server-side. I don't know how to do the session without seeing the "login" button of Facebook on the server side.
How to do this? Any thoughts on how to make my PHP page, when executed, create a new Facebook object from the Facebook PHP class, and then plug in the whatever Access Token and UID maybe, and then post to the wall of the user?
Thanks!
Answered here:
Facebook offline access step-by-step

How to make a website that functions as a website and a facebook app?

I have a website based game that has login accounts that I want to integrate into facebook (not facebook connect, I want to use an iframe canvas page).
My question is how can I authenticate a user and how can I check if a user is coming from facebook or directly from the site.
I have been playing around with require_login() using the PHP library. My main fear is how can I authenticate that the GET parameters from facebook are indeed from facebook? If I can do that then I can store their facebook session id and Uid in a session as login credentials.
My other worry is that the GET variable may get passed as a reffer to an external link.
Finally... I find in some browsers that with require_login() that it breaks out of the iframe and gets into an eternal look continually adding additional authtoken's to the URL.
Hope someone can help
Yes you can create a app that works independently as well as facebook app. For the facebook you will have to use the facebook's iframe method to work under facebook.
You can verify the request comes from Facebook by verifying the signature in the same way that Facebook checks that API requests come from your application. With the PHP client library you can use the validate_fb_params() method of the Facebook class to do this automatically.
Bear in mind that session key's are temporary so the user will keep needing to authenticate with Facebook through your application otherwise the key expires within the hour. You may also run into a 3rd party cookie issue with Safari if you're hoping to store the session key in a cookie, and you'll need a compact privacy for quite a few other browser/privacy setting combinations as well. Something like:
<?php
header('P3P: CP="CAO PSA OUR"');
?>
in an include would do it.
And yes: the session key may be passed to external sites as in the referrer properties. It's just one of the security flaws that the platform currently has. The only way around that is either to redirect all external clicks through a handler which removes the referrer, or redirect on page load to strip the fb_sig_ss parameter out.