Facebook iFrame app links send outside - facebook

any FB experts here? After reading about 15 thread on FB forums I don'T know where to go next =(
We have an iFrame FB app: http://apps.facebook.com/myapp
all links used in app are like: href="http://www.mysite.com/index.php?parm=value ..."
now when I click on any link, I am out of facebook and land on our server.
Don't really know how to solve this! using links with facebook server ins't an option.
Thanks guys for some hints!

This is because Facebook loses all of the authentication variables and is unable to determine that the concurrent requests belong to the same session, which results in "breaking out" of the iframe and ending up on your own server pages instead of within Facebook.
Anytime a page is served through Facebook, the request received at your server will include a number of GET variables sent by Facebook, these variables are collectively known as the "Facebook Authentication Signature" which proves to your server that the request actually is valid and originated from Facebook; likewise, when your server sends the response, the inclusion of these variables proves to Facebook (by a combination of the session_key, api_key, and sig digest) that your server is the application it claims to be.
In order to persist the session within your iframe app without breaking out to your server, you must include these parameters on each link's query string. Here is a simple function that will produce the query string for you, so you simply need to append the result of this function to each link URL in your application:
function fb_sig_urlQueryString() {
$query = '';
foreach ($_GET as $k => $v) {
if (strpos($k, 'fb_sig') === 0) {
if ($i++ > 1) $query .= '&';
$query .= $k.'='.$v;
}
}
return $query;
}

Do you mean clicking a link in the iframe goes to your site intead? If you do you could try setting the "target" attribute of the html anchor to "_self" which should open the link in the iFrame.

I was having this problem. After appending all the FB querystring parameters from the initial IFrame to each of the urls in my links, they started opening in the right windows.
See here for an example http://www.keywordintellect.com/facebook-development/facebook-iframe-authentication-across-pages-ajax-requests/

Related

Facebook Send dialog with API Error code: 100 ('link' is invalid)

I want to provide users with the ability to send money to their Facebook friends through our app (Exvo) by the means of sending an URL to the invitation page via Facebook.
I'm using the 'Send' Facebook dialog (with a redirect to the Facebook webiste). The exact url I'm redirecting the user to is (to field has been redacted):
https://www.facebook.com/dialog/send?app_id=637466739616439&description=You+can+create+an+Exvo+Account+to+accept+this+money+transfer.&display=page&link=https%3A%2F%2Fwww.exvo.com%2Finvitations%2F9fb77bda665f0ae8f58843daec80a29b&name=Pawe%C5%82+Go%C5%9Bcicki+would+like+to+send+you+0.01+EUR&picture=https%3A%2F%2Fthemes.exvo.com%2Fstylesheets%2Fimages%2Fcustom_images%2Flogo.png&redirect_uri=https%3A%2F%2Fwww.exvo.com&to=username
This present me with a Facebook 'Send' dialog. When I type a custom message and press 'Send', I'm presented with this error:
API Error Code: 100
API Error Description: Invalid parameter
Error Message: 'link' is invalid.
The link param (extracted from the above URL and decoded) is this:
https://www.exvo.com/invitations/9fb77bda665f0ae8f58843daec80a29b
which is a valid URL, returning a proper 200 response. Using the Facebook debugger I can see that the provided URL does not generate any errors:
https://developers.facebook.com/tools/debug/og/object?q=https%3A%2F%2Fwww.exvo.com%2Finvitations%2F9fb77bda665f0ae8f58843daec80a29b
Only warnings about inferred properties (I have added those at one point as well, but it did not help).
Also note, that once in a while (like 1 in 10), when I click 'Send', the message gets through and I don't see any errors, which makes it even weirder.
Why is this error happening? What am I doing wrong?
This might not have been the problem in your case, but just for discoverability: make sure that the URL you are sharing is publicly available on the internet (i.e. not within your firewall or on a local computer). FB needs to visit your URL to verify its authenticity.
Like mpcabd has pointed out above, make sure to remove anything with fb, fbdev, facebook in the url because when I did, it solved the issue for me. It is probably a bug or a security measure by Facebook. You are always required to pass a redirect_uri with the link and try mentioning a title as well.
Also your link and redirect_uri must be within your domain that you have provided for the app. Ex: if your app domain in app settings is http://stackexchange.com, you cannot share a link like say https://stackoverflow.com/apps/php/fbsdk/etc/login.php, instead you have to share the link https://stackexchange.com/apps/php/etc/login.php which has worked for me
echo "<a href='https://www.facebook.com/dialog/send?app_id=YOUR_APP_ID&name=Thanks&link=".$linkToShare."&redirect_uri=".$linkToRedirectTo."'/>Send</a>";
You can also assign $title to something.
I figured out something weird, the same thing happened today on the site I manage, the problem seemed to be that the link contains the word facebook in it, so try to remove [facebook, fb, or f if it was a whole word] from your url, it should work, I had a url like open/ID/facebook/ and the only way it worked when I changed it to fopen/ID/ which looks stupid!
So may be in your case this is the problem:
https://www.exvo.com/invitations/9fb77bda665f0ae8f58843daec80a29b
Try to change your url to something without fb or facebook or anything similar.
I had this issue using the send dialog only. I was using dynamic querystring parameters on a common URL. The common URL has been scraped by Facebook but each iteration of the common URL and the querystring parameters would result in this error if Facebook had not scraped that exact URL previously.
I fixed the issue by forcing Facebook to scrape the URL before I attempt to send it via the FB UI Send Dialog. Use the FB API to hit graph.facebook.com with the URL posted in the id parameter and a scrape parameter set to true.
Like so:
FB.api('https://graph.facebook.com/', 'post', {
id: '[URL]',
scrape: true
}, function(response) {
FB.ui({
method: 'send',
name: '[name]',
picture: '[Picture URL]',
link: '[URL]',
description: '[description]'
});
});
I also answered with this solution to the same problem here.
Doing the following fixed it for me:
shorter token (this string in the link param: 9fb77bda665f0ae8f58843daec80a29b, which was 32 characters long, now is at 16) as advised by gkimsal
accepting October 2013 breaking changes, which required me to introduce OpenGraph tags to the page and drop name, description and picture_uri params that I was including when constructing the Send dialog redirect uri
Now Facebook, before displaying the Send dialog to the user, must fetch my page beforehand to retrieve the data (from OG: title, description and image) required to display a proper dialog to the user. I think this is what helped the most in my case.

Facebook PHP SDK usage stand alone - how do the Facebook sessions/cookies work?

I'm utilizing the Facebook PHP SDK on its own. I do not want to use the JS SDK at all.
Because getUser(); from the SDK can return a user id even if the user is not logged in, I have opted for using a try/catch statement to check if the user is logged in.
try
{
$me = $CI->facebook->api('/me');
$CI->our_fb['is_fb']='YES';
echo "hello";
}
catch(FacebookApiException $e)
{
echo "catch";
}
This statement is included in the global include file of all of my files (for simplicity).
So, depending on the situation, I generate a Facebook login URL. The expected functionality is that the user logins to Facebook, authorises the app, is returned to the redirect URI set in the login URL at which point the try statement will execute, and $CI->our_fb['is_fb'] will be set.
This is however not happening.
If the user is already logged into Facebook and the app is authorised, it works perfectly. SUCCESS
If the user is not logged into Facebook, once redirected the variable is not set. FAILURE
If the user is logged in but the app is NOT authorised after redirect the variable is not set. FAILURE.
In the latter two cases if you simply refresh the page, the variable is set - SUCCESS. Refreshing the page is however unnecessary/pointless extra effort.
My problem is that if you need to login to FB/or authorise the app e.g the first time you login with FB, you have an additional unneeded refresh, and I don't know why.
I suspect it is something to do with the cookie/session? Which saves the access token that I assume is returned/passed to the SDK automatically not being set at the same time?
Anyone got any ideas?
If you're having an app on facebook (tab or canvas). PHP SDK only get the User ID on initial loading of a page because a signed_request is sent with the request to your app.
But, when the app refreshes, the signed_request is lost (as it's facebook who send it).
So, in this case, you can append the signed_request to every URLs your use in your app - but that's really not optimal as the signed_request won't be regenarated - neither refreshed.
Your only real option is to rely on the JS SDK to set cookie correctly and allow getUser to work as expected. This is required because you're considered as a third-party app in Facebook (being in an iframe) and most browser will block you from setting cookies - so you need a work around handled by the JS SDK for you. You can search for cross-domain cookies or third-party cookie for explanation about the workarounds, but these workaround only work via JS scripting and iframe management.
Also, be sure to setup the JS SDK correctly: channel file, cookie allowed, and send P3P headers (for IE).
You can also check this related question: A proper approach to FB auth
About website, the same mostly stays (but you have no signed_request). At this point, seriously consider using the JS SDK as it's way easier. Or else, you can make sure your app flow follow these guidelines: https://developers.facebook.com/docs/concepts/login/login-architecture/
The way I am seeing this is, you are trying to avoid that refresh if the user is not logged in and precedes to log in after the page has initially loaded.
So what you can do is make an ajax request to another page on your site, say for example id.php, which just loads the php sdk and echo $userid; and then you can grab the user id after login without the refresh.
Basically the cookie is used to save the signed request and session is used to save 'state', 'code', 'access_token', 'user_id'. If the above are present PHP SDK uses them, no matter if they are valid or not.
I think your problem lies in the CODE sent by facebook. Specifically these lines in base_facebook.php:
if ($code && $code != $this->getPersistentData('code')) {
$access_token = $this->getAccessTokenFromCode($code);
...
protected function getAccessTokenFromCode($code, $redirect_uri = null) {
if (empty($code)) {
return false;
}
if ($redirect_uri === null) {
$redirect_uri = $this->getCurrentUrl();
}
...
Because CODE is issued for specific url sometimes there is such situation: Visitor arrives on www.example.com. He givies permissions and is redirected to example.com/login. But the code is not valid there, so the getUserAccessToken returns false. When you refresh the page you get same urls and everything's fine.
You're on the right track of not using getUser() because as I wrote above it's taken from the session if available.

Facebook share to refer back traffic to the iframe page tab

SO here's what I am after. I have a FB page tab that runs the content of the site https://site.com/
I set up a FB share link to share a page aboutus.html. When I share it FB allows me to share this URL https://site.com/aboutus.html, but how can i send the traffic directly to the iFrame on the page tab? For example https://www.facebook.com/fan_page/app_331267943480920398/whatever_aboutus.html
I know it is possible because I saw it one day - cant remember now where.
Thanks.
You can't pass in filenames this way, that's only supported on Canvas Apps.
The best workaround to replicate this is using the app_data parameter. Basically, have your landing page (as defined in your app settings), be some kind of server side script which listens to the Signed Request, specifically the app_data parameter. Then you have that script load content based on the contents of that.
So as an example, let's imagine I want to load http://mybasedomain.com/foo.php or http://mybasedomain.com/bar.php. I direct users to https://www.facebook.com/PAGENAME/app_APPID?app_data=foo or https://www.facebook.com/PAGENAME/app_APPID?app_data=bar, then on my landing page, I have a simple if/else statement to parse that and render the relevant content -
<?php
// Assumes you have this parse_signed_request function - https://gist.github.com/872837
// And a $config array, which contains your app_secret
$signed_request = parse_signed_request($_REQUEST['signed_request'], $config['AppSecret']);
if ($signed_request['app_data'] === 'foo') {
include('foo.html');
} else if ($signed_request['app_data'] === 'bar') {
include('bar.html');
} else {
include('index.html');
}

Facebook Signed Request empty after reload

I have a probleme with my Signed Request on my facebook application. The first time is good, and i know if the user like or not my app. But when I reload the application (link, form, like) i loose the Signed Request, (only refresh [F5], and unlike works)..
I realy don't understand why ??
Links don't work anymore :(
This is my test page : https://www.facebook.com/pages/TestCactOos/255835411190164
And the test app : https://www.facebook.com/pages/TestCactOos/255835411190164?sk=app_335457189856398
On app, you can see $facebook, $_REQUEST and $_SERVER informations.
Thank you all for your time and help.
The signed request is in the header of the referral from Facebook. It's not maintained from link to link, since the subsequent referrals will be from your own pages. Use the signed_request to get some info and keep that in your session between pages.
You are just one time able to get the signed_request. That is exactly when Facebook loads your App in an iframe. Then you must have to save the signed_request for further usage (subpages). There you have to check for the data via $_REQUEST or fall back to your stored signed_request values.
Here is an small example of the fbHelper component. I hope this might give you some ideas how to handle the issue:
Source: http://www.facebook.com/HelperComponentlCommunity/app_412923142052609
if(array_key_exists('signed_request', $_REQUEST))
$signed_request = $_REQUEST['signed_request'];
elseif(array_key_exists('signed_request' . $this->pageId, $_SESSION))
$signed_request = $_SESSION['signed_request' . $this->pageId];
else
return false;
$facebook_data= $this->parse_signed_request($signed_request);

Authenticated Referrals & Server-Side Auth Flow - What is the redirect_uri?

From an authenticated referral (such as from a timeline story) to my website, I am trying to use the server-side authentication flow to obtain an access token for the referred user. I need to pass my app secret, the auth code, and the original redirect URI to the Facebook access token endpoint. Since I did not initiate the authentication request, how do I determine the original redirect_uri?
The link from the Facebook timeline looks like:
http://www.facebook.com/connect/uiserver.php?app_id=153644678059870&method=permissions.request&redirect_uri=http%3A%2F%2Fwww.wnmlive.com%2Fpost%2F141833948%3Ffb_action_ids%3D10100708033267487%26fb_action_types%3Dwnm-live%253Acomment%26fb_source%3Drecent_activity&response_type=code&display=page&auth_referral=1
So I figure that the redirect URI I need to pass is:
http%3A%2F%2Fwww.wnmlive.com%2Fpost%2F141833948%3Ffb_action_ids%3D10100708033267487%26fb_action_types%3Dwnm-live%253Acomment%26fb_source%3Drecent_activity
The URI that the user is ultimately redirected to is:
http://www.wnmlive.com/post/141833948?fb_action_ids=10100708032119787&fb_action_types=wnm-live%3Apost&fb_source=recent_activity&code=AQALK-Mwb_Nwi4z7FWnFaL6tEXvNtVJiRKrgarG9X73sp22TJyk8v2GWKtuXuevJk4hPSRNnuNpEgZXLFdOS_k-pY-mE15DYytIa8Y7VdSw3VL-XYi-CR9BCqRQGq4uBJvSSdZayCp6MWzDMaNqWd5r8OhKVnOhg_yDlvfoLl21N2SMwkJaOfD5mlPnPb5A-Q4A#_=_
Is it safe to assume that I can just chop off everything starting with the "&code=" and use that as the redirect URI?
According to a Facebook engineer, the redirect_uri is the current URI up until the "&code=". The code will always be the final query string name/value pair. I have also verified that this works.
Currently (Aug 23 2012) Facebook is adding parameters after the code= , for instance,
http://apps.coincident.tv/newgirltalk/mobile/?ref=bookmarks;code=AQCZmt8n9NyfKNj8Ea9yzeCYCh-m6FcrbFqqnpQRYpfTwsO8DCk5E6CIbYig1I7g5RxDZxNs7pLcQZDdfjdLJy-8IE4BAW56VPNVADTIa9zxsFEVGLTCjfP7tuSNAIeNZdWecI53pQipnt4YpnawoRXDYVVylFZnWoVYdMtVCaOjZ5DUrN9VSByNVkV5ojOoCEY;fb_source=bookmark_favorites;count=0;fb_bmpos=4_0
Deleting everything from code= doesn't yield an access token, nor does carefully deleting just the code=....; section.
This can be recreated by adding a Facebook bookmark pointing to your app, opening www.facebook.com in your mobile device browser, and then going to your app via the bookmark.
In addition to what Carl said,
I narrowed the issue to be because of specific ref parameter.
If you have referral oauth enabled, I'll be unabled to exchange the code for an access_token with specific ref.
Examples:
http://m.facebook.com/apps/App_name/?ref=bookmarks
http://m.facebook.com/apps/app_name/?ref=m_notif
Those will not work with referral oauth no matter what redirect_uri you use for generating the access_token. There are probably other ref parameters that doesn't work.
It's very annoying because we can't have mobile web app working with this issue
As Carl pointed out, there are additional parameters after code. Unlike Carl, if I strip those off and use the resulting url as the redirect uri, it works.
$redirecturi = $_SERVER['SCRIPT_URI'];
$delimiter = "?";
foreach ($_GET as $key=>$val) {
if ($key == "code") break;
$redirecturi .= $delimiter.$key."=".rawurlencode($val);
$delimiter = "&";
}
// now I can use $redirecturi to exchange the code for a token
http://developsocialapps.com/authenticated-referrals-facebook-apps/
I filed a bug on Facebook here : https://developers.facebook.com/bugs/141862359298314
If this still affects your app, please go subscribe.