Facebook Login and Iframe redirection - facebook

I am building an Facebook IFrame App. I am using the below javascript code to request user to login and allow permissions for the application, after which they are supposed to be redirected to the iframe app. The code works correctly. But, I have two issues with it.
a. as soon as the app loads in IFrame, it redirects to a page (http://www.facebook.com/connect/uiserver.php?app_id=......) and displays a large facebook icon. When I click this icon it redirects to facebook login page. I want my app to redirect to the login page directly instead of showing the inbetween facebook icon page.
b. When the user clicks 'Allow' button for the requested permission in facebook, the page redirects to my main site (http://www.mysite.com) instead of the iframe application(http://apps.facebook.com/myapp).
I have pasted my javascript below, this works with above quirks.
var api_key = 'xxxxxxxxxxxxxxx';
var channel_path = 'xd_receiver.htm';
FB_RequireFeatures(["Api"], function () {
FB.Facebook.init(api_key, channel_path);
var api = FB.Facebook.apiClient;
// require user to login
api.requireLogin(function (exception) {
FB.Connect.showPermissionDialog("publish_stream");
});
});
Help much appreciated.

I have remembered something!
You must use target="_top" in all your links and redirections in a iframe application!
Hope I help you.

Thanks for your answers.
I used the solution posted by McKAMEY(Facebook API: FB.Connect.requireSession issues) with few changes, and it works as intended, without showing the intermediate facebook icon page, and also it redirects after authentication to the iframe app correctly.
I have posted below the working solution in case someone needs it.
var api_key = 'xxxxxxxxxxxx';
var channel_path = './xd_receiver.htm';
var canvas_url = "http://apps.facebook.com/myappxxxx/"// ensure your canvasurl has a '/' at the end!
function Initialize() {
FB_RequireFeatures(["Api"], function () {
FB.Facebook.init(api_key, channel_path);
FB.ensureInit(function () {
FB.Connect.ifUserConnected(
function () {
var uid = FB.Connect.get_loggedInUser();
if (!uid) {
authRedirect();
return;
}
},
authRedirect);
});
});
}
function authRedirect() {
//This is the Sample URL Structure for redirecting to facebook
//http://www.facebook.com/connect/uiserver.php?
//app_id=XXXXXXXXXXXXX&
//next=xxxxxxxxxx_success_url_here_XXXXXXX&
//display=page&
//perms=XXXXXX_comma_seperated_permissions_list_hereXXXXXX&
//fbconnect=1&
//method=permissions.request
window.top.location.href = "http://www.facebook.com/connect/uiserver.php?app_id=" + encodeURIComponent(api_key) + "&next=" + encodeURIComponent(canvas_url) + "&display=page&perms=publish_stream&fbconnect=1&method=permissions.request";
}
Initialize();

Note on redirecting within a frame to the Facebook login page. You have to use javascript to redirect the entire page since the login page passed the X-Frame-Options:DENY header and modern browsers will prevent you from sending the user to the URL if that header is present. Solution is to use javascript::window.top.location = ''; to redirect the whole page

I'm not sure on the middle page between redirection but what does your apps canvas and connect url point to?
The redirection after login should go to that page unless you have this overridden somewhere in your code.
Change the urls in the settings on fb to apps.facebook.com/myapp if that's not what its set to.

You may use the new Facebook Graph API (http://developers.facebook.com/docs/api) to handle authentication. First, you must check if you have the access_token:
$access_token = $_REQUEST['access_token'];
if($access_token != NULL) {
...
}
else {
// the following javascript
}
And the javascript is:
<script type="text/javascript">
top.location.href = '<?= "https://graph.facebook.com/oauth/authorize?client_id=".$appid."&redirect_uri=".$appurl."oauth_redirect" ?>'
</script>
You must have a file oauth_redirect.php like this:
<?php
$code=$_REQUEST['code'];
$url = "http://graph.facebook.com/oauth/access_token?client_id=".$appid."&redirect_uri=".$appurl."oauth_redirect&client_secret=".$appsecret."&code=$code";
$curl = curl_init();
// SET URL FOR THE POST FORM LOGIN
curl_setopt($curl, CURLOPT_URL,$url);
curl_setopt($curl, CUPROPT_SSL_VERIFYPEER, true);
curl_setopt($curl, CUPROPT_SSL_VERIFYHOST, true);
curl_setopt($curl, CURLOPT_FOLLOWLOCATION ,1);
curl_setopt($curl, CURLOPT_HEADER ,0);
curl_setopt($curl, CURLOPT_RETURNTRANSFER ,1);
// EXECUTE 1st REQUEST (LOGIN)
$response = curl_exec ($curl);
?>
<script type="text/javascript">
top.location.href = '<?= $appurl."?".$response ?>';
</script>
Finally, you can return to your index page (the $appurl variable) and test if the user has permission testing access_token presence.
Hope it helps!

Related

Cakephp Facebook Plugin - Sharing through an action

I am using Nick Baker's (webtechnick) CakePHP / Facebook plugin which is awesome and works great, however I have a question that I can't seem to even come close to answer for.
How would I bypass the use of a share button and share directly through an action?
For instance, I make a post through my site and the post adds to the DB as it should, it also shoots a post to the logged in users Twitter account through the action. How can I also have this action handle sharing it to my FB account (connection has already been made).? I tried the first thing I think anyone would obviously try $this->Facebook->share() directly in the action, too no avail...
Any thoughts or solutions would be of great help...
UPDATE AFTER ANSWER
Thx for the help spooney. I voted your answer up because you are 100% spot on from what I can tell. I am loading the JS SDK.
function init($options = null, $reload = true) {
if (empty($options)) {
$options = array();
}
if ($appId = FacebookInfo::getConfig('appId')) {
$session = json_encode($this->Session->read('FB.Session'));
if ($reload) {
$callback = "FB.Event.subscribe('auth.login',function(){window.location.reload()});";
} else {
$callback = "if(typeof(facebookReady)=='function'){facebookReady()}";
}
$callback .= "FB.Event.subscribe('auth.logout',function() {window.location = '/bastards/users/logout'});";
$init = '<div id="fb-root"></div>';
$init .= $this->Html->scriptBlock(
<<<JS
window.fbAsyncInit = function() {
FB.init({
appId : '{$appId}',
status : true, // check login status
cookie : true, // enable cookies to allow the server to access the session
xfbml : true, // parse XFBML
oauth : true // use Oauth
});
{$callback}
};
(function() {
var e = document.createElement('script');
e.src = document.location.protocol + '//connect.facebook.net/{$this->locale}/all.js';
e.async = true;
document.getElementById('fb-root').appendChild(e);
}());
JS
, $options);
return $init;
} else {
return "<span class='error'>No Facebook configuration detected. Please add the facebook configuration file to your config folder.</span>";
}
}
I have no problem pulling in the user information and working with all that. I have accomplished posting to FB from my site, but it was only through a link, using FB.ui...
<br><font style="color:#FFF; text-decoration:none;padding-left:27px;">post to wall</font><br>
<script>
function publishStory() {
FB.ui({
method: 'feed',
name: 'message name',
caption: 'message caption ',
description: 'description goes here',
link: 'the url current page',
picture: 'if you want to add an image'
},
function(response) {
console.log('publishStory response: ', response);
});
return false;
}
</script>
I have tried replacing the code above with...
<br><font style="color:#FFF; text-decoration:none;padding-left:27px;">post to wall</font><br>
<script>
function publishStory() {
var body = 'Reading JS SDK documentation';
FB.api('/me/feed', 'post', { message: body }, function(response) {
if (!response || response.error) {
alert('Error occured');
} else {
alert('Post ID: ' + response.id);
}
});
}
</script>
But it errors everytime.
I should also throw in there that the post on the users FB wall isn't really coming from the site persay, it's a post from the user on their own wall basically stating, "I made a post on ladala.com, you should go check it out at ."
So now I'm at the point that I need to figure out how to run FB.ui through the action that submits the post.
Based on our conversation, I figured I would just put a more complete description in an answer.
You can fire a share call using the JavaScript SDK.
First, you would need to load the JavaScript SDK as described in the Loading section of https://developers.facebook.com/docs/reference/javascript/.
Once loaded into your page, the two calls you want to look at are FB.getLoginStatus, and FB.api. FB.getLoginStatus will give you back a response telling you if the user is logged in to facebook, and if they have approved your application. This link will describe the functionality of getLoginStatus, but in short, you need to check for response.connected(and then possibly do another call to confirm a user's permissions, if required).
If the user is logged in and has approved your app, you can then attempt to make an API call using FB.api. Keep in mind to do this, you will likely need the user to have allowed the publish_stream permission.
Your code would look something like this:
//Do FB initialization
FB.getLoginStatus(function(response) {
if (response.status === 'connected') {
FB.api('/me/feed', 'post', { message: body }, function(response) {
if (!response || response.error) {
//Post was successful
}
});
}
});
This can be triggered any way you want. On page load, on click, on completion of some other event, etc.
Keep in mind this is just one way to implement this. Also, if you are trying to share something with your FB application, and it is not working, you should confirm that you have all the permissions required to do so.

Facebook - How can i post to a company using the javascript sdk?

Im new to facebook posting but have had some success with posting offline with a user account but cannot post offline with a company page.
I have created my own "Facebook App" called "Nicks Poster App" via my own personal facebook account. I have granted three permissions (offline_access,read_stream,publish_stream) to the app for both my personal page and my company page.
i did this by following these steps for each account...
Creating the app...
1. Login to facebook with the account you want linked to the app
2. Follow this link http://www.facebook.com/developers/apps.php#!/developers/createapp.php
3. Create your app and take a note of you App Id and your App secret Id.
Giving the correct rights to the app and getting the access_token..
Method 1:
1. Get the account in question to login to facebook
2. However you like, direct the user to this link (replacing <App-Id> with the App Id of the created app) https://graph.facebook.com/oauth/authorize?client_id=<App-Id>&scope=offline_access,read_stream&redirect_uri=http://www.facebook.com/connect/login_success.html
3. Take a note of the result of the “code” querystring.
4. Goto this url (replace “<APP-ID>” with you appId and “<APP-SECRET>” with your apps secret id and “<code>” with the copied code)
https://graph.facebook.com/oauth/access_token?client_id=<APP-ID>&redirect_uri=http://www.facebook.com/connect/login_success.html&client_secret=<APP-SECRET>&code=<code>
5. Copy what you see, minus the expires querystring. That is your access_token.
After i had the access token for both accounts i used this code to make the post.
<!-- FACEBOOK -->
<div id="fb-root"></div>
<script>
(function () {
var e = document.createElement('script');
// replacing with an older version until FB fixes the cancel-login bug
e.src = document.location.protocol + '//connect.facebook.net/en_US/all.js';
//e.src = 'scripts/all.js';
e.async = true;
document.getElementById('fb-root').appendChild(e);
} ());
</script>
<!-- END-OF-FACEBOOK -->
<script>
//initialise
window.fbAsyncInit = function () {
FB.init({
appId: '351023398277068',
status: true, // check login status
cookie: true, // enable cookies to allow the server to access the session
xfbml: true, // parse XFBML
oauth: true // Enable oauth authentication
});
};
function sendPost(inMessage) {
var opts = {
message: inMessage,
access_token: '<SAVED-TOKEN>'
};
FB.api('/me/feed', 'post', opts, function (response) {
if (!response || response.error) {
alert('Posting error occured');
}
else {
alert('Success - Post ID: ' + response.id);
}
});
}
</script>
When executing the "sendPost" command with the perameter 'Test post', it will work for my personal account (providing i put my access_token in place). This does not work for my company page, and im at a loss as to why(i do put my acess_token in place).
Facebok also havent documented this very well and it makes it hard to make progress, does anyone understand why this doesnt work for company pages?
Thank you in advance.
You can set the "to" parameter to target the page you wish to post to, "manage pages perms will be needed if you wish to post as your page to your page as the application.
<div id="msg"></div>
<script>
// uid is the id of the page or user you wish to post to.
function feedthis2(uid) {
// calling the API ...
var obj = {
method: 'feed',
to: ''+uid+''
};
function callback(response) {
document.getElementById('msg').innerHTML = "Post ID: " + response['post_id'];
}
FB.ui(obj, callback);
}
feedthis2('AnotherFeed'); // to http://facebook.com/anotherfeed
//feedthis2('135669679827333');
</script>

Share button/post to wall - Facebook API?

I don't want to use the FB like button and apparently "share" has been deprecated.
What I am trying to do is have users click "share"/"post to wall" from my website, and it then places a post on their newsfeed/profile with information on my website/url.
I can't seem to find any code around that will do this- does anyone have an example?
And do they have to connect first? Or can it check if they're logged in, if not, login and it shares automatically?
Thanks!
This is possible in two ways:
You can use the facebook Javascript SDK if you have an app:
FB.ui({
method: 'feed',
link: 'absolute url',
name: 'testtitle',
caption: 'testcaption',
description: 'testdescription',
picture: 'absolute picurl',
message: ''
});
Note that "message" MUST be empty, you can also just remove it.
Without an app (no user can block the app and never get anything from the app anymore, but only possible with popup):
open a popup window with Javascript for the facebook sharer:
http://www.facebook.com/sharer.php?u=<url to share>&t=<title of content>
Note that everything needs to be urlencoded. Of course you can also just use it as a link. And don't forget the og tags in this case.
Edit: Please be aware that "auto sharing" is not allowed on facebook. you have to present the user what you want to share in his name and he has to be able to accept it and add his personal message. would only be possible with an app and an authorized user anyway.
Btw, both methods explained here work without user login/authorization.
Edit2: There is also a "share" method with FB.ui now, to post a link or use Open Graph Actions/Objects.
If you have a dynamic web site as I do, you may strongly want my code.
Note 1: You can't do that if you don't have an app! If you don't have
an app you can simply go to https://developers.facebook.com/apps and
create one.
Note 2: Read my code comments!
Code:
<?
$redirect = "http://www.SITE.com/thanks.html"; //After sharing, you redirect your visitor to thanks.html or just to the home page. Note that the URL given is the URL you set for your app!
$link = curPageURL(); //URL to the shared page (I will give you the function curPageURL() later).
$title = Title(); //Title of the shared page (Note If you don't have a dynamic website you can simply ignore the PHP part)
$descriptionTag = Description(); //Description of the shared page
$pic = Img(); //Image of the post or the logo of your website
echo "<script>
FB.init({appId: \"YOU_APP_ID_HERE\", status: true, cookie: true});
function postToFeed() {
// calling the API ...
var obj = {
method: 'feed',
redirect_uri: '".$redirect."',
link: '".$link."',
picture: '".$pic."',
name: '".$title."',
caption: '".$descriptionTag."',
description: 'You_May_Want_To_Say_Something_About_Your_Web_Site_Here!'
};
function callback(response) {
document.getElementById('msg').innerHTML = \"Post ID: \" + response['post_id'];
}
FB.ui(obj, callback);
}
</script>"; ?>
<a href="#" onclick='postToFeed(); return false;'>Share To Facebook</a>
Note:
Don't forget to set YOUR APP ID in the code!
You need to use the function curPageURL() in order to share the current PHP page!
Code:
<?
function curPageURL() {
$pageURL = 'http';
if (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] == "on") {$pageURL .= "s";}
$pageURL .= "://";
if ($_SERVER["SERVER_PORT"] != "80") {
$pageURL .= $_SERVER["SERVER_NAME"].":".$_SERVER["SERVER_PORT"].$_SERVER["REQUEST_URI"];
} else {
$pageURL .= $_SERVER["SERVER_NAME"].$_SERVER["REQUEST_URI"];
}
return $pageURL;
}
?>
Don't forget to declare the function curPageURL() at the beginning of the code I'm giving to you!

In Facebook FB.ui (method: permissions.request) user is not redirect to proper location

Hi i m trying to show permission dialog using following code:
$permission = $facebook->api(array('method' =>'users.hasAppPermission','ext_perm'=>'publish_stream','uid'=> $uid));
if($permission != '1')
{
echo "<script type='text/javascript'>
var dialog = {
method: 'permissions.request',
perms: 'publish_stream',
redirect_uri: 'http://apps.facebook.com/abcd/'
};
FB.ui(dialog,null);
</script>";
}
This code works fine but problem is that when user allow to permissions he is not redirected to redirect_uri location(that is my canvas page) instead it goes to canvas url (that is my server's url). how to solve this problem Help me.
You can add the following javascript code in your page:
FB.Event.subscribe('auth.sessionChange', function(response) {
if (response.session) {
window.location.href = '/whatever/here';
} else {
// The user has logged out, and the cookie has been cleared
}
});

Facebook Login with Open Graph

//if user is logged in - do this
function login() {
FB.api('/me', function(response) {
document.getElementById('fb-info-block').innerHTML =
"Welcome, " + response.name + ".<br /><br />" +
"<fb:like href = 'www.whitbreaddesign.com' show_faces = 'false' width = '100' action = 'like' colorscheme = 'light'></fb:like>";
});
}
Can someone tell me how I can add the facebook users profile pic to the above code...After someone connects to my site they will get a Welcome, (their name) to my site....How can I also add there profile picture after Login along with the Welcome note?
I hope by now you've solved this but if not you need to use the access token supplied by the getLoginStatus response.
Check out: http://developers.facebook.com/docs/api
The example links for Users, Pages, Events etc are misleading. If you hover over the links you'll see that Facebook adds "?access_token=%TOKEN%" to each link. That's what you'll need to do.
You function will probably look something like this depending on how you work it.
Hope this helps.
window.fbAsyncInit = function()
{
FB.init({ appId: 'Your App Id', status:true, cookie:true, xfbml:true });
FB.getLoginStatus(function(response){
if(response.session){
/* Fetch Access Token Data Here and set to Global Var */
var access_token = response.session.access_token;
/* Other Init Functions */
}
});
function login()
{
FB.api('/me', function(response){
/* Use Access Token Data Here */
document.getElementById('fb-info-block').innerHTML = (
"Welcome, " + response.name + ".<br /><br />" +
'<br/><img src="https://graph.facebook.com/me/picture?access_token='+ access_token +'"/><br/>'+
"<fb:like href = 'www.whitbreaddesign.com' show_faces = 'false' width = '100' action = 'like' colorscheme = 'light'></fb:like>"
);
});
}
}
<img src="http://graph.facebook.com/me/picture">
Why don't you use fbml tags:
fb:profile-pic and fb:name
(http://developers.facebook.com/docs/reference/fbml/)
And once, you put that FBML inside your div, you may need to call
FB.XFBML.Parse() javascript function.
(It pre-exists as I assume you must have included facebook's javascript by now)
The me shortcut will only work if the person is logged in to fb. You can also use their facebook Id:
<img src="https://graph.facebook.com/220439/picture">