I got a notification from Facebook saying that they will invalidate calls from URIs not listed in the Valid OAuth redirect URIs this coming March 2018 and I think they are requiring us to Enable Strict Mode for Redirect URIs. Link about this can be found here.
I have been using their PHP SDK with Strict Mode disabled for a year now without any problem however when I do enable strict mode and place there the redirect url which is: https://nino-dot-dynamic-osprey-93721.appspot.com/admin/fb-callback_admin.php - it returns an error as seen below each time I try to Login with Facebook:
Graph returned an error: Can't Load URL: The domain of this URL isn't included in the app's domains. To be able to load this URL, add all domains and subdomains of your app to the App Domains field in your app settings.
Note that I'm simply using FB's default PHP SDK Login code (https://developers.facebook.com/docs/php/howto/example_facebook_login) which have login.php and fb-callback.php links and I'm not using any custom OAuth workflows.
I noticed that the redirect URL generated contains the code and state parameters:
site.com/admin/fb-callback_admin.php?code=somecode&state=somestate
I think this is the reason why I'm getting the error because it only expects a redirect URL of https://nino-dot-dynamic-osprey-93721.appspot.com/admin/fb-callback_admin.php without any trailing parameters.
How do you guys think of getting around this issue of Enabling Strict Mode given that the response of the redirect URL through the below code:
$helper = $fb->getRedirectLoginHelper();
$permissions = ['email']; // Optional permissions
$loginUrl = $helper->getLoginUrl('https://nino-dot-dynamic-osprey-93721.appspot.com/admin/fb-callback_admin.php', $permissions);
echo htmlspecialchars($loginUrl);
is generated from FB's PHP SDK by default?
Change
$accessToken = $helper->getAccessToken()
to
$accessToken = $helper->getAccessToken('http://www.example.com/admin/fb-callback_admin.php');
I had the same issue and found this answer in this thread, which seems to resolve the problem for me:
Graph returned an error: Can't Load URL: The domain of this URL isn't included in the app's domains
Not sure why this works, though, but glad it did.
I was facing the same issue, Actually, this comes from the facebook graph sdk.
I got this information from here
Also, a quick and dirty change that seemed to fix this error for me
was adding 'code' to the list of params to remove in
FacebookRedirectLoginHelper
later facebook itself released the updated package which seems fixed the issue.
make sure you have the latest version of facebook-graph-sdk at the time of this answer, the version is 5.6.2
My site has some URLs that are rewritten by .htaccess... i.e. this:
http://lastminuteislandvacation.com/villa/15/st-john-rental-villa-angelica
is invisibly re-written to:
http://lastminuteislandvacation.com/villa.php?id=15
However, when I plug all this in the Facebook Linter, I get this error message:
"Errors That Must Be Fixed: There was an error in fetching the object at URL
'http://lastminuteislandvacation.com/villa/15/st-john-rental-villa-angelica',
or one of the the URLs specified via a redirect or the 'og:url'
property including one of
http://www.lastminuteislandvacation.com/villa/15/st-john-rental-villa-angelica."
What does that mean, and is it a problem I need to worry about or is it just the Linter complaining?
FWIW as far as I can tell, all my open graph tags on the page are fine, and there's nothing unusual about rewriting a URL via .htaccess. My shares on Facebook seem to look and work correctly, with all the right metadata, image, etc. In other words: there's no problem that I can see, but that whole "Errors That Must Be Fixed" part has me mildly concerned.
When I try your urls in the debugger the results I get are just fine, there are no errors what so ever.
For the short (.php) version I get this:
Fetched URL: http://lastminuteislandvacation.com/villa.php?id=15
Canonical URL: http://lastminuteislandvacation.com/villa/15/st-john-rental-villa-angelica
URL for Likes: http://lastminuteislandvacation.com/villa.php?id=15
And for the longer one I get this:
Fetched URL: http://lastminuteislandvacation.com/villa/15/st-john-rental-villa-angelica
Canonical URL: http://lastminuteislandvacation.com/villa/15/st-john-rental-villa-angelica
In the Scrape Information section.
Also, at the bottom (Urls section) you can see that they both get the same Graph API url
When sharing one of my pages on FB, I want to display something different. Problem is, I prefer not to use the og: elements, but to recognize FB user-agent.
What is it? I can't find it.
For list of user-agent strings, look up here. The most used, as of September 2015, are facebookexternalhit/* and Facebot. As you haven't stated what language you're trying to recognize the user-agent in, I can't tell you more information. If you do want to recognize Facebook bot in PHP, use
if (
strpos($_SERVER["HTTP_USER_AGENT"], "facebookexternalhit/") !== false ||
strpos($_SERVER["HTTP_USER_AGENT"], "Facebot") !== false
) {
// it is probably Facebook's bot
}
else {
// that is not Facebook
}
UPDATE: Facebook has added Facebot to list of their possible user-agent strings, so I've updated my code to reflect the change. Also, code is now more predictible to possible future changes.
"Facebook's user-agent string is facebookexternalhit/1.1 (+http://www.facebook.com/externalhit_uatext.php)..."
Hi
Small, yet important, correction -> Facebook external hit uses 2 different user agents:
facebookexternalhit/1.0 (+http://www.facebook.com/externalhit_uatext.php)
facebookexternalhit/1.1 (+http://www.facebook.com/externalhit_uatext.php)
Setting you fitler to 1.1 only may cause filtering issues with 1.0 version.
For more information about Facebook Bot (and other bots) please refer to Botopedia.org - a Comunity-Sourced bot directory, powered by Incapsula.
Besides user-agent data, the directory also offers an IP verification option, allowing you to cross-verify an IP/User-Agent, thus helping to prevent impersonation attempts.
Here are the Facebook crawlers User Agent:
FacebookExternalHit/1.1
FacebookExternalHit/1.0
or
facebookexternalhit/1.0 (+http://www.facebook.com/externalhit_uatext.php)
facebookexternalhit/1.1 (+http://www.facebook.com/externalhit_uatext.php)
Note that the version numbers might change. So use a regular expression to find the crawler name and then display your content.
Update:
You can use this code in PHP to check for Facebook User Agent
if(preg_match('/^FacebookExternalHit\/.*?/i',$agent)){
print "Facebook User-Agent";
// process here for Facebook
}
Here is ASP.NET code. You can use this function to check if the userAgent is Facebook's useragent.
public static bool IsFacebook(string userAgent)
{
userAgent = userAgent.ToLower();
return userAgent.Contains("facebookexternalhit");
}
Note:
Why would you need to do that? When you share a link to your site on Facebook, facebook crawls it and parses it to get some data to display the thumbnail, title and some content from your page, but it would link back to your site.
Also, I think this would lead to cloaking of the site, i.e. displaying different data to user and the crawlers. Cloaking is not considered a good practice and may search engines and site take note of it.
Update: Facebook also added a new useragent as of May 28th, 2014
Facebot
You can read more about the facebook crawler on https://developers.facebook.com/docs/sharing/webmasters/crawler
Please do note that sometimes the agent is visionutils/0.2 . You should check for it too.
Facebook User-Agents are:
FacebookExternalHit/1.1
FacebookExternalHit/1.0
facebookexternalhit/1.0 (+http://www.facebook.com/externalhit_uatext.php)
facebookexternalhit/1.1 (+http://www.facebook.com/externalhit_uatext.php)
facebookexternalhit/1.0 (+https://www.facebook.com/externalhit_uatext.php)
facebookexternalhit/1.1 (+https://www.facebook.com/externalhit_uatext.php)
I'm using the code below to detect FB User-Agent in PHP and it works as intended:
$agent = $_SERVER['HTTP_USER_AGENT'];
if(stristr($agent, 'FacebookExternalHit')){
//Facebook User-Agent
}else{
//Other User-Agent
}
Short solution is to check pattern, and not to load all the mess to user each time
<?php
# Facebook optimized stuff
if(strstr($_SERVER['HTTP_USER_AGENT'],'facebookexternalhit')) {
$buffer.='<link rel="image_src" href="images/site_thumbnail.png" />';
}
?>
In the perspective of user-agent modifications on FB side, it is maybe safer to use a regex like that :
<?php
if (preg_match("/facebook|facebot/i", $_SERVER['HTTP_USER_AGENT'])){
do_something();
}
?>
You can find more information about Facebook crawler on their doc: https://developers.facebook.com/docs/sharing/webmasters/crawler
And if you want to block facebook bot from accessing your website (assuming you're using Apache) add this to your .htaccess file:
<Limit GET POST>
BrowserMatchNoCase "Feedfetcher-Google" feedfetcher
BrowserMatchNoCase "facebookexternalhit" facebook
order deny,allow
deny from env=feedfetcher
deny from env=facebook
</Limit>
It also blocks google's feedfetcher that also can be used for cheap DDoSing.
Firstly you should not use in_array as you will need to have the full user agent and not just a subset, thus will quickly break with changes (i.e. version 1.2 from facebook will not work if you follow the current preferred answer). It is also slower to iterate through an array rather than use a regex pattern.
As no doubt you will want to look for more bot's later so I've given the example below with 2 bot names split in a pattern with the pipe | symbol. the /i at the end makes it case insensitive.
Also you should not use $_SERVER['HTTP_USER_AGENT']; but you should filter it first incase someone has been a little nasty things exist in there.
$pattern = '/(FacebookExternalHit|GoogleBot)/i';
$agent = filter_input(INPUT_SERVER, 'HTTP_USER_AGENT', FILTER_SANITIZE_ENCODED);
if(preg_match($pattern,$agent)){
echo "found one of the patters";
}
A bit safer and faster code.
You already have the answer for Facebook above, but one way to get any user agent is to place a script on your site that will mail you when there is a visit to it. For example, create this file on your domain at, say, https://example.com/user-agent.php :
<?php
mail('you#youremail.com', 'User Agent', $_SERVER['HTTP_USER_AGENT']);
Then, visit Facebook, and type the link to the script there, and hit space bar. You don't actually have to share anything, just typing the link in and a space will cause Facebook to fetch a preview. You should then get an email with Facebook's user agent.
Another generic approach in PHP
$agent = $_SERVER['HTTP_USER_AGENT'];
$agent = trim($agent);
$agent = strtolower($agent);
if (
strpos($agent,'facebookexternalhit/1.1')===0
|| strpos($agent,'facebookexternalhit/1.0')===0
){
//probably facebook
}else{
//probably not facebook
}
For some odd reason, i do not receive a "signed_request" when using IE. If i use the same application in firefox/chrome i get the signed request! has anyone had this problem and is there a solution.
I tried to search it up, but i can never get anything close to what i am asking (signed_request usually just takes over search and i get a bunch of documentation on how to parse it).
So i decided, well this is strange!
<?php print_r($_POST) // or request ?>
I made this as a page. In FF and Chrome, both give me the post information, but IE does not give me anything... just
Array( )
Thanks!
signed request is the included for case where user access your content via facebook. That should be signed to the server... and therefore it should not depends on the client browser. check you code to see if you have done something like redirecting the request when the session / user is invalid.
A solution that worked for me was to put this header in my tab page:
<?php
header('P3P: CP="CAO PSA OUR"');
header('P3P: CP="HONK"');
?>
I've found this solution here: http://hasin.me/2011/09/30/story-about-blue-e-iframed-web-application-wastage-of-6-hours-and/
Our app uses the PHP- aswell as the JS-SDK of Facebook. We are able to access the users-images and the images of his friends thru both sdks. The upload of photos into user-albums works aswell.
The user currently selects one of his images which gets manipulated on our server and uploaded to Facebook into the album it came from. That part works. We now want to post that uploaded image onto the users wall. Facebook itself generates a post on the users feed about newly uploaded images (can be disabled on the uploading request) but those posts are not customizable. The standard facebook-post request requires an url to the optional photo. The documentaton states that it is not allowed to link to images from the facebook content delivery-network (which has been confirmed by the graph api as it throws an appropriate error).
Is it possible to create a standard wall-post that contains a gallery-image somehow? Ideally it would use the gallery-popup but that is clearly super-nice-to-have.
An externally hosted copy is an (unwanted) workaround that we already know. Reuploading the image is an option as long as it does not show up in the gallery twice.
Simple solution :
Get a tinyurl for you fbcdn'ed picture through tinyurl api:
Example with url from above :
http://tinyurl.com/api-create.php?url=http://a4.sphotos.ak.fbcdn.net/hphotos-ak-snc3/13943_196960329960_683709960_2997879_7206516_n.jpg
Returns :
http://tinyurl.com/3ta96kh
Then use this url as the "picture", I tried it here and it works ! : http://jsfiddle.net/dwarfy/VYAeD/27/
There was another solution here but It seems facebook corrected it and it still says the error with facebook CDN when I post using https://graph.facebook.com/PICTURE_ID as picture instead of the FBCDN image url.
I think it's the best solution ...
My example doesn't use the link parameter but you could set it to the gallery image ...
Indeed you can't post to users' walls image saved on fb BUT also you don't have to save it physically on you server. if you want to post an image, for example:
http://a4.sphotos.ak.fbcdn.net/hphotos-ak-snc3/13943_196960329960_683709960_2997879_7206516_n.jpg
facebook as you know will not accept this. but ther is no problem to post something like this: http://yourserver.com/script.php?image=a4.sphotos.ak.fbcdn.net/hphotos-ak-snc3/13943_196960329960_683709960_2997879_7206516_n.jpg (without http:// -- its important, if you include http:// facebook will find out what's going - and we don't want it:)
script.php is a php file on your server that do this:
<?
$url = "http://".$_GET['image'];
header('Content-type: image/jpeg');
echo file_get_contents($url);
?>
or something like this:
<?
$url = "http://".$_GET['image'];
$image = imagecreatefromjpeg($url);
//some image modifications here//
header('Content-type: image/jpeg');
echo imagejpeg($image, null, 100);
?>
you can also add an database with urls and post something like this: http://yourserver.com/script.php?imageid=ID hiding all images' real paths.
If you want to save on traffic after publishing images on walls just redirect:
<?
//if published then just redirect
$url = "http://".$_GET['image'];
header('Location: '.$url); die();
?>
You have to make the copy of that image otherwise there is no way you can use this image in standard post dialog.
Use PHP function
copy()
I know you are looking for any other alternative but to create a spare image on your server or any other server is the only solution.