My server use only https with an htaccess redirect at root level, when my tab app is called from a FB page if the user use an http connection I lost the signed request.
Everyone knows a solution?
How to force Facebook to use https when call a tab?
thanks
luc
How to force Facebook to use https when call a tab?
In theory, HTTP status codes 307 (Temporary Redirect) and 308 (Permanent Redirect) should be used for this, since they require the method to stay the same, so the client would have to fetch the resource that’s been redirected to using POST with the same data again.
However, I have no experience how well this works with the browsers that are out there.
Probably better to “redirect” client-side, using JavaScript. Of course, that requires a resource that is available using HTTP only, and is not redirected server-side to it’s HTTPS counterpart.
In the future, this “problem” will go away on it’s own, I assume – since Facebook announced end of last year that they will move all users to HTTPS; so I think some time from now we won’t be required to give a HTTP URL for canvas/page tab apps any more, and use just one HTTPS version.
I resolved in this way:
In the FBapp manager I used as http url a page created on a different server that accept http.
In this page I used the following code .
$signed_request = $facebook->getSignedRequest();
$page_id = $signed_request["page"]["id"];
$fql_query_url = "https://graph.facebook.com"
."/$page_id?fields=link"
."";
try {
$fql_query_result = #file_get_contents($fql_query_url);
$fql_query_obj = json_decode($fql_query_result, true);
} catch(Exception $o){ }
$pageinfo = $fql_query_obj[link];
$pageinfo = str_replace("http://","https://",$pageinfo);
$tabpage = "$pageinfo"."?sk=app_$appId";
echo "
<!-- force tab iframe -->
<script type=\"text/javascript\">
top.location.replace('$tabpage');
</script>
";
?>
that's all
Related
I am building some forms using the html input tabs in Facebook.
My form actions are post and insert linking to externally hosted php
function files.
The problem is, if the user isn't using Facebook's new https setting, a pop up
is shown with "un secure form"
Is there a why to provide a secure handler externally hosted or is this something
I would have go deeper into Facebook ap making with?
Facebook loads your app into an iframe (using POSTing a form).
When the user is using https with facebook they use the Secure Canvas URL property from the app settings, and when the user is not on secure browsing they use the Canvas URL.
Because of that, your page is not loaded from https but http, which is why that warning is shown to the user by the browser.
What you can do is to check when your page is loading which protocol is used and if it's not https then reload the page from https.
Something like (using window.location object):
var location = window.location;
if (location.protocol != "https:") {
window.location.href = "https://" + location.host + "/" + location.pathname + location.search
}
Or if you don't expect to have urls in your querystring you can simply replace:
window.location.href = window.location.href.replace("http", "https");
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.
In my canvas page, I try to authenticate the user the way it is described in http://developers.facebook.com/docs/guides/canvas/, by using essentially this code (example code from developers.facebook.com):
<?php
$app_id = "YOUR_APP_ID";
$canvas_page = "YOUR_CANVAS_PAGE_URL";
$auth_url = "http://www.facebook.com/dialog/oauth?client_id="
. $app_id . "&redirect_uri=" . urlencode($canvas_page);
$signed_request = $_REQUEST["signed_request"];
list($encoded_sig, $payload) = explode('.', $signed_request, 2);
$data = json_decode(base64_decode(strtr($payload, '-_', '+/')), true);
if (empty($data["user_id"])) {
echo("<script> top.location.href='" . $auth_url . "'</script>");
} else {
echo ("Welcome User: " . $data["user_id"]);
}
?>
The problem is, the first time the user authorizes my canvas application, Facebook doesn't pass a signed_request parameter when redirecting back (as described in the example code), but a code parameter. When accessing the application the second time (already having confirmed the rights), it passes a signed_request parameter as expected.
Why does it pass a code parameter the first time? The documentation doesn't explain when Facebook passes a code / signed_request parameter.
The problem was that for $canvas_page, I used the canvas URL (e.g. mysite.com/canvas) instead of the canvas page URL (e.g. apps.facebook.com/myapp).
I think you need to append "&response_type=token" to your authentication url:
https://www.facebook.com/dialog/oauth?client_id=YOUR_APP_ID&redirect_uri=YOUR_URL&response_type=token
Then you get back something that looks like:
http://apps.facebook.com/APP_NAME/#access_token=YOUR_APP_ID%YADA_YADA_YADA0&expires_in=3948
And you can extract it with some Javascript:
if (window.location.hash.length == 1)
{
var accessToken = window.location.hash.substring(1);
}
Facebook uses the code parameter to authenticate your application. In the documentation, it states:
*If the user presses Allow, your app is authorized. The OAuth Dialog will redirect (via HTTP 302) the user's browser to the URL you passed in the redirect_uri parameter with an authorization code*
To complete the authorization, you must now take the code parameter and your app secret and pass it to the Graph API token endpoint (paraphrasing the documentation). This will grant you access to the access token. From this point onward, your application will not require the code parameter for this user because they are already authenticated.
Facebook uses the signed_request to share information with your application. The documentation states three scenarios in which it will pass the signed request. These are:
A signed_request is passed to Apps on Facebook.com when they are loaded into the Facebook environment
A signed_request is passed to any app that has registered an Deauthorized Callback in the Developer App whenever a given user removes the app using the App Dashboard
A signed_request is passed to apps that use the Registration Plugin whenever a user successfully registers with their app
So to conclude, the code parameter is only sent to authenticate the application, while the signed_request is utilized to pass information once the application has been authorized.
Saj-and is very correct.
I too struggeled with this alot.
When setting the redirect_uri to my domain name, I got an infinate redirect loop.
When setting the redirect_uri to the facebook app url, I got an error saying the url is not on my domain and so cannot be accessed.
It took the "/" at the end to solve this
I had the same problem with my canvas app, I fixed it by simply redirecting to my application's canvas url in the case that there is a code GET request parameter. After that Facebook sends me POST request that contains the signed_request parameter as expected. Here is the Python Django snippet:
if 'code' in request.GET.keys():
return HttpResponseRedirect(FACEBOOK_CANVAS_URL)
# ...rest of your canvas handling code here
I struggled with this issue (not getting oauth ID in the signed_request and instead get the "code" after user approves the app) for over a week, and this post (and few others posts) helped me get very close to resolving the issue (I was using my apps canvas URL instead of the canvas page url in the redirect URI, and I didn't specify the namespace in the settings).
After making these corrections, I faced a different issue where the app approval page won't show up for a new user and instead facebook throws the message" application has an error etc.. and finally I figured I was missing a / at the end of the canvas page url in my redirect url.. I had it as https://apps.facebook.com/myappname instead of https://apps.facebook.com/myappname/ in the redirect uri. Adding the / at the end resolved the issue and when a new user access my app using https://apps.facebook.com/myappname (if the user is already logged in ) facebook shows the approval page (upon receiving the response from my server) and once the user approves the app, facebook sends the signed-request with the required auth code to my application. Hope this will be useful for anyone else who might encounter the same issue.
Just to clear the confusion about the code parameter.. Facebook will always send this parameter when user allows the application.. however the signed_request parameter is sent using post or some other method.. it is not sent in the url.. You can access it using $_REQUEST['signed_request']
I had a similar problem that was solved when I assigned a namespace to my app, so it would look like apps.facebook.com/myapp and not apps.facebook.com/1234.
I was experiencing the problem you describe with firefox and with third-party cookies disabled.
I enabled third-party cookies and then the signed_request was suddenly available.
Is there a way to deny direct access to the application server for a facebook application?
Facebook loads the application via an iFrame src=http://app-domain/, but you can clearly view the page source and find out that domain and copy paste the URL into a browser and view the application directly.
There is this signed_request and oauth_token in the API, I was wondering how to use that or if I can use that to limit direct access to the application.
So if a user inputs in the browser your application's URL he gets redirected to Facebook.
Thank you.
EDIT:
I found a way that also works with form submission.
// Signed request
$signed_request = $facebook->getSignedRequest();
if(!$signed_request) header("Location: " . $settings['appBaseUrl']);
This redirects the browser while accessing the application directly and not through facebook.
It will not work if javascript is disabled.
<script type="text/javascript">
var isInIFrame = (window.location != window.parent.location) ? true : false;
if(!isInIFrame){
window.location = 'link-of-application-page';
}
</script>
You'll need some Javascript to detect whether you're in Facebook's frame and if you're not, redirect to it.
I found a way that also works with form submission. (Works for me, it might not work for you. Test it first.)
// Signed request
$signed_request = $facebook->getSignedRequest();
if(!$signed_request) header("Location: " . $settings['appBaseUrl']);
This redirects the browser while accessing the application directly and not through facebook.
I'm trying to integrate my project with Facebook. I'm taking baby steps at first and just trying to login, get a Facebook session, and get some user data. I'm developing it locally so my Facebook application settings are:
site URL: http://127.0.0.1:8888/mySite/
The canvas URL is the same as above. I haven't specified a site domain.
However, when I click on the login button, I get an error:
API Error Code: 191
API Error Description: The specified URL is not owned by the application
Error Message: redirect_uri is not owned by the application.
At the moment I haven't written any server-side code to deal with redirects, etc. All I've done is add the JavaScript SDK based on the tutorial in Facebook for Websites.
What have I done wrong? It's obviously something to do with my Facebook application settings, but I can't see what!
UPDATE:
To answer the API Error Code: 191
The redirect_uri should be equal (or relative) to the Site URL.
Tip: Use base URLs instead of full URLs pointing to specific pages.
NOT RECOMMENDED: For example, if you use www.mydomain.com/fb/test.html as your Site URL and having www.mydomain.com/fb/secondPage.html as redirect_uri this will give you the 191 error.
RECOMMENDED: So instead have your Site URL set to a base URL like: www.mydomain.com/ OR www.mydomain.com/fb/.
I went through the Facebook Python sample application today, and I was shocked it was stating clearly that you can use http://localhost:8080/ as Site URL if you are developing locally:
Configure the Site URL, and point it
to your Web Server. If you're
developing locally, you can use
http://localhost:8080/
While I was sure you can't do that, based on my own experience (very old test though) it seems that you actually CAN test your Facebook application locally!
So I picked up an old application of mine and edited its name, Site URL and Canvas URL:
Site URL: http://localhost:80/fblocal/
I downloaded the latest Facebook PHP-SDK and threw it in my xampp/htdocs/fblocal/ folder.
But I got the same error as yours! I noticed that XAMPP is doing an automatic redirection to http://localhost/fblocal/ so I changed the setting to simply http://localhost/fblocal/ and the error was gone BUT I had to remove the application (from privacy settings) and re-install my application and here are the results:
After that, asked for the publish_stream permission, and I was able to publish to my profile (using the PHP-SDK):
$user = $facebook->getUser();
if ($user) {
try {
$post = $facebook->api('/me/feed', 'post', array('message'=>'Hello World, from localhost!'));
} catch (FacebookApiException $e) {
error_log($e);
$user = null;
}
}
Results:
For me, it was a missing app domain. Go into the app, and make sure that you have the root of your site set up as an app domain. See screenshot.
This is just because of a URL mistake.
Whatever website URL is specified should be correct.
I mentioned website URL as http://localhost:3000/
and domain as localhost, but in my browser I was running http://0.0.0.0:3000/.
When I ran server as localhost:3000 it solved the problem.
As I mentioned, the site URL as localhost Facebook will redirect to the same, if we are running
0.0.0.0:3000, it will rise error that "Given URL is not allowed by the Application configuration".
I was also facing the same problem when I am using the facebook authentication method.
But I rectify that issue with following changes in Facebook api (Apps >> My App >> Basic).
I removed the url which i have given in
===> App on Facebook (Canvas URLs)
I gave site url only in
===> Website with Facebook Login option
Then i gave that AppId and App Secret in my webpage.
So by clicking on login button, It ask for access permissions then it redirect it to give url (Website with Facebook Login ).
I fixed this by passing the redirect url to the FacebookRedirectLoginHelper::getAccessToken() in my callback function:
Changing from
try {
$accessToken = $helper->getAccessToken();
}
...
to
try {
$accessToken = $helper->getAccessToken($fbRedirectUrl);
}
...
I am developing on a vagrant box, and it seems FacebookRedirectLoginHelper::getCurrentUrl() had issues generating a valid url.
Had the same problem:
$params = array('redirect_uri' => 'facebook.com/pages/foobar-dev');
$facebook->getLoginUrl($params);
When I changed the redirect_uri from the devloper page to the live page, 191 Error came up.
So I deleted the $params:
$facebook->getLoginUrl();
After the app-request now FB redirects to the app url itself f.e.: my.domain.com
What I do now is checking in index.php of my app if I'm inside FB iframe or not. If not I redirect to the live FB page f.e.:
$app = 'facebook.com/pages/foobar-live';
$rd = (isset($_SERVER['HTTP_REFERER'])) ? parse_url($_SERVER['HTTP_REFERER'], PHP_URL_HOST) : false;
if ($rd == 'apps.facebook.com' || (!isset($_REQUEST['signed_request']))) {
echo '<script>window.parent.location = "'.$app.'";</script>';
die();
}
I have noticed also that even if you specify your website under secion - Website With Facebook Login -> Site url as e.g. http://example.com, but if your App Domains section is empty, and you open website as www.example.com you will get this error, too. To avoid it in "App Domains" section write example.com, that will allow subdomains, like www.example.com, something.example.com etc
in the facebook App Page, goto the basic tab. find "Website with Facebook Login" Option.
you will find Site URL: input there put the full URL ( for example http://Mywebsite.com/MyLogin.aspx ). this is the URL you can use with the call like If the APP ID is 123456789
https://graph.facebook.com/oauth/authorize?client_id=123456789&redirect_uri=http://Mywebsite/MyLogin.aspx&scope=publish_actions
Something I'd like to add, since this is error 191 first question on google:
When redirecting to facebook instead of your own site for a signed request, you might experience this error if the user has secure browsing on and your app does redirect to facebook without SSL.
Working locally...
I couldn't get the feeds api to work, but the share api worked pretty much straight away with no problems.
For me it's the Valid OAuth Redirect URIs in Facebook Login Settings. The 191 error is gone once I updated the correct redirect URI.