Auto Login Facebook User After Accepting Permissions - javascript

I'm trying to login users automatically into my site who have already allowed our facebook app, initially I was going to use :
var cb = function(response) {
if (response.status === 'connected') {
FB.api('/me', function(response) {
$.post( url, { 'op':'facebook','name':response['name'],'id':response['id'],'email':response['email']},
function( data ) {
parent.location.reload();
});
});
} else {
alert('You are not logged in');
}
};
FB.login(cb, { scope: 'publish_actions,publish_stream,read_stream,email' });
Although using that it opens a facebook popup, blocked by many popup blockers and browsers when done in an automatic manner like this and will also display for users who have no allowed our app.
I want it to be done descretely but I'm not sure how :S
If anyone could show me how to log them in using javascript that would be great :)

Prompting a user to login should be hinged off of a user generated event, like clicking on an element. Most browsers will block attempts to automatically open new windows unless there is enough confidence that the user has requested the action.
If you want to automatically detect a visitor's login status when they load your page, you should hook onto the various auth events exposed by the Javascript SDK ("auth.authResponseChange", "auth.login", etc), or manually request the visitor's status using the "FB.getLoginStatus" method. You can read more about these events at https://developers.facebook.com/docs/reference/javascript/FB.getLoginStatus/

Managed to get it working! Read the facebook tutorial again and this is what I came up with
window.onload=function(){
var url = "http://mysite.com/";
FB.getLoginStatus(function(response) {
if (response.status === 'connected') {
FB.api('/me', function(response) {
$.post( url, { 'op':'facebook','name':response['name'],'id':response['id'],'email':response['email']},
function( data ) {
parent.location.reload();
});
});
}
});
};

Related

Facebook API share feed popup sometimes get blocked

I have a page where you can share something.
First im logging in with FB.login()
FB.login(function(response) {
if (response.authResponse) {
sharePost(imgName,socket);
} else {
//do nothing if not logged in....
}
}, {scope: 'public_profile,email,user_friends'});
Then im using the following share
FB.ui(
{
method: 'feed',
link: 'myurl',
caption: 'mycaption',
display:'popup',
title: 'title,
picture:'myimg.png',
description:'mydescription,
name:'myname'
},
// callback
function(response) {
if (response && !response.error_code) {
if(waitedTooLong == false)
{
successfullLogin(socket);
}
console.log("shared");
} else {
successfullLogin(socket);
console.log("not shared");
}
}
)};
Sometimes it blocks the popup after logging in. Sometimes not.
I thought about removing FB.login() but I need the scope for other actions.
You need to use FB.ui dialogs on user interaction (= mouse click), not in the asynchronous callback function of FB.login. Modern browser detect it as unauthorized popup and block it. Also, it´s a bad idea to present a feed dialog right after authorization. Present a Login Button and use FB.login, then present a Share Button and use FB.ui feed or FB.ui share.
Btw, you don´t even need to authorize the user for FB.ui, so you can just skip FB.login and use it when you really need it.

Facebook Login via PHP SDK, then use JS SDK

I have developed an application where users login via facebook (PHP SDK); now I would like to add JS SDK too, because I want to implement a generic friend selector (http://facebook-friend-selector.codersgrave.com/) that works with JS SDK. I have two questions about:
1) Can mixing the two SDK lead to problems?
2) I added the JS SDK code as explained in the documentation and tried a simple request
FB.api('/me/friends', function(response) {
alert(JSON.stringify(response));
});
but I get an error (unknown error); I also tried a dialog box
FB.ui({
method: 'feed',
link: 'https://developers.facebook.com/docs/dialogs/',
caption: 'An example caption',
}, function(response){});
but the box appears and suddenly disappears. I think the issue is related to the authentication...I guess, since my users are authenticated via PHP, that I need to pass the access token to JS, but how? This question Passing the Facebook Authorization Token from PHP to Javascript seems to be exactly what I need but I don't understand the answer: it says to store the token in a cookie, but how can JS know about it, which name the cookie should have?
Finally, if I do something like
FB.getLoginStatus(function(response) {
if (response.status === 'connected') {
alert('connected');
var uid = response.authResponse.userID;
var accessToken = response.authResponse.accessToken;
}
});
I actually get a "connected" alert, that means that JS knows that the user is logged in, even if the login was via PHP, so where is the problem?
Solved. My code contained two stupid mistakes, this is the correct code:
function test(){
FB.getLoginStatus(function(response) {
if (response.status === 'connected') {
var uid = response.authResponse.userID;
var accessToken = response.authResponse.accessToken;
FB.api('/me/friends', function(response) {
alert(JSON.stringify(response));
});
}
});
}
Test
In the first version the call to the friends method was outside the getLoginStatus method, so it was called before setting the variable accesToken, furthermore, I haven't the "return false" statement after the test() call.

FB.getLoginStatus doesn't work in Chrome even sandbox disable

I follow railscast to add "sign in with Facebook" feature in my site, there is no problem to login. But when try to logout, it seems that FB.getLoginStatus never got fire even when I disable Sandbox Mode in facebook developer app settings (as suggested in some other discussion):
(function() {
jQuery(function() {
$('body').prepend('<div id="fb-root"></div>');
return $.ajax({
url: "" + window.location.protocol + "//connect.facebook.net/en_US/all.js",
dataType: 'script',
cache: true
});
});
window.fbAsyncInit = function() {
FB.init({
appId: 'xxxxxomittedxxxxx',
cookie: true,
status: true,
xfbml: true,
oauth: true
});
$('#sign_in').click(function(e) {
e.preventDefault();
return FB.login(function(response) {
if (response.authResponse) {
return window.location = '/auth/facebook/callback';
}
});
});
return $('#sign_out').click(function(e) {
FB.getLoginStatus(function(response) {
if (response.authResponse) {
return FB.logout(response.authResponse);
}
});
return true;
});
};
}).call(this);
The reason I know the FB.getLoginStatus never get in (or doesn't work) is I replace the body with:
FB.getLoginStatus(function(response) {
return alert("I am here!");
});
and I cannot see my alert while "sign_out" click.
I am running both Chrome and Firefox having the same behaviour. Could anybody help to spot what am I missing? Thanks a lot.
Let me describe more specific about the "behaviour" I encountered:
sign in with Facebook from mysite.com the first time a Facebook login window will popup and ask for email and password, and I can sign in to my site perfectly ok and work as expected
then I click on sign_out button from mysite.com/users/1, it looks like it sign out ok.
then sign in with Facebook from mysite.com again, now it won't popup the Facebook login window anymore and login to mysite.com/users/1 directly without asking email and password!
if I open another browser window and go to facebook.com and logout from there, then when I sign in with Facebook from mysite.com, it will popup a Facebook login window now and ask for my email and password.
I would like my site to behave: "when logout from mysite.com/users/n and sign in with Facebook again from mysite.com, the Facebook login window shall popup"
Anyone could be of help? Thanks a lot.
EDIT:
Further investigation found the "root" cause might be still: the sign out is under the different route (or page) of the sign in route and FB.getLoginStatus just cannot be fire under the mysite.com/signout. The error message from firebug indicates that "Given URL is not allowed by the Application configuration.: One or more of the given URLs is not allowed by the App's settings. It must match the Website URL or Canvas URL, or the domain must be a subdomain of one of the App's domains."
To proof it is the route issue, I put a sign out link in the same route (page) as sign in route which is the root route mysite.com as specified in the "Website with Facebook Login", everything works and can logout as expected:
<%= link_to "sign out facebook", "#" , id: "sign_out" %>
by the way the sign_out js is revised to get rid of FB.logout(response.authResponse) uncaught [object Object] error, because FB.logout expects function as parameter:
return $('#sign_out').click(function(e) {
FB.getLoginStatus(function(response) {
if (response.authResponse) {
FB.logout();
}
}, true);
});
};
So, the bottom line: FB.getLoginStatus might still have a bug which cannot handle the call from a different route than sign in route. (I tested with Chrome, Firefox and Safari and all behave the same but not true for IE10. Somehow IE10 works even sign out at different route.)
Any comment from people who have similar problem? Please advise. Thank you very much in advance.
Try adding true as second parameter to getLoginStatus, as stated in FB dev doc:
FB.getLoginStatus(function(response) {
// this will be called when the roundtrip to Facebook has completed
}, true);
This should avoid caching.
Another option is to subscribe to events:
FB.Event.subscribe('auth.login', function(response) {
// do something with response
});
All from here
Comment if you have questions.
EDIT:
I modified your script a little bit, removed unneeded code parts. You had too many returns that are not needed. I tried sign out within this modified script, it works as you need it.
Events subscription is for check purposes.
<head>
<title>Exam entry</title>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.10.1/jquery.min.js"></script>
</head>
<body>
<div id="fb-root"></div>
<input type="button" value="Sign in" id="sign_in" />
<input type="button" value="Sign out" id="sign_out" />
<script type="text/javascript">
window.fbAsyncInit = function () {
FB.init({
appId: '586844044669652',
cookie: true,
status: true,
xfbml: true
});
// Here we subscribe to the auth.authResponseChange JavaScript event. This event is fired
// for any authentication related change, such as login, logout or session refresh. This means that
// whenever someone who was previously logged out tries to log in again, the correct case below
// will be handled.
FB.Event.subscribe('auth.authResponseChange', function (response) {
// Here we specify what we do with the response anytime this event occurs.
if (response.status === 'connected') {
// The response object is returned with a status field that lets the app know the current
// login status of the person. In this case, we're handling the situation where they
// have logged in to the app.
testAPI();
} /*else if (response.status === 'not_authorized') {
// In this case, the person is logged into Facebook, but not into the app, so we call
// FB.login() to prompt them to do so.
// In real-life usage, you wouldn't want to immediately prompt someone to login
// like this, for two reasons:
// (1) JavaScript created popup windows are blocked by most browsers unless they
// result from direct interaction from people using the app (such as a mouse click)
// (2) it is a bad experience to be continually prompted to login upon page load.
FB.login();
} else {
// In this case, the person is not logged into Facebook, so we call the login()
// function to prompt them to do so. Note that at this stage there is no indication
// of whether they are logged into the app. If they aren't then they'll see the Login
// dialog right after they log in to Facebook.
// The same caveats as above apply to the FB.login() call here.
FB.login();
}*/
});
$('#sign_in').click(function (e) {
e.preventDefault();
FB.login(function (response) {
if (response.authResponse) {
//return window.location = '/auth/facebook/callback';
}
});
});
$('#sign_out').click(function (e) {
FB.logout(function (response) {
console.log("Here logout response", response);
});
});
};
// Here we run a very simple test of the Graph API after login is successful.
// This testAPI() function is only called in those cases.
function testAPI() {
console.log('Welcome! Fetching your information.... ');
FB.api('/me', function (response) {
console.log('Good to see you, ' + response.name + '.');
});
}
// Load the SDK asynchronously
(function (d) {
var js, id = 'facebook-jssdk', ref = d.getElementsByTagName('script')[0];
if (d.getElementById(id)) { return; }
js = d.createElement('script'); js.id = id; js.async = true;
js.src = "//connect.facebook.net/en_US/all.js";
ref.parentNode.insertBefore(js, ref);
}(document));
</script>
</body>

Facebook Javascript API sending two requests

In my application I have a function like this one:
getProfile = function() {
FB.api('/me', function(response) {
console.log(response);
});
return false;
};
Which requests the "me" object from the Facebook Graph API over JavaScript, and it works as expected when I attach it to the onClick event of a regular link or call it from the console directly, but when I try to call it from the Facebook log in button:
<fb:login-button onlogin="getProfile()">
Get Profile
</fb:login-button>
I get the expected response only if I am logged out of Facebook and subsequently log in through the dialog; if I click the button while I'm already logged in, I get this:
And if I push the response to the browser:
getProfile = function() {
FB.api('/me', function(response) {
console.log(response);
var
profile = document.getElementById('profile'),
p = document.createElement('p');
p.innerHTML = response.first_name;
profile.appendChild(p);
});
return false;
};
Of course I get two paragraphs with my name in them.
Can anyone spot what I'm doing wrong? So far my Googling has me convinced that this is related to the way the SDK handles log in events (firing on every page load) but I can't figure out how I'm supposed to account for that in the application code.
I believe the onlogin event fires when you load the page because you are logged into Facebook. Then, when your user clicks the button, it also triggers the event. If you're not logged in in the first place, then the onlogin event doesn't fire on load.
UPDATE: to avoid this, simply don't hook the getProfile to the onlogin event except inside an if statement based on the FB.getLoginStatus method http://developers.facebook.com/docs/reference/javascript/FB.getLoginStatus/ Simply put, if you're logged in, don't attach an onlogin event, otherwise do an FB.Event.subscribe http://developers.facebook.com/docs/reference/javascript/FB.Event.subscribe/ on the onlogin event and your method will run whenever the user logs in through your XFBML-generated login button.
FB.getLoginStatus(function(response) {
if (response.status === 'connected') {
//print the response data into the paragraph here
} else if (response.status === 'not_authorized') {
// the user is logged in to Facebook,
// but has not authenticated your app
FB.event.subscribe( 'auth.login', function(){
getProfile();
});
} else {
// the user isn't logged in to Facebook.
}
});

Facebook permissions in IE Causing infinite facebook loop

I am trying to get permissions for a facebook app I am making, but every time I try to run the app in IE8 I cannot get the permissions box to show up. I have tested the app in firefox and it can open fine, and get all the permissions fine (i dont ask for any special ones).
When I run the debugger in IE8 I see that once the program hits FB.getLoginStatus(function (response) { (see code below) it then moves into an infinite loop of code written by facebook.
I think the issue is because of how I am making the permissions call. I have a form that I use for a login that will call the permissions method once the user attempts to login to the site. Here is the form and button in the form I use:
<form id = "membershipInfo" method = "post" action = "Login.aspx">
<input type = "button" id = "submitInfo" class = "MemberInfo" value = "Take Me There!" onclick = "authorize(acceptPermissions, rejectPermissions)"/>
And here is the auth method I use:
function authorize(successCallback, failureCallback) {
FB.getLoginStatus(function (response) {
//****** DOES NOT MAKE IT PAST HERE *******//
if (response.session) {
// logged in and connected user, carry on
session = response.session;
//Set access token
accessToken = response.session.access_token;
//Call success callback
successCallback();
} else {
// no user session available, Lets ask for perms
FB.ui(
{
method: 'permissions.request',
perms: permissionString //(equals "" )
},
function (response) {
if (response && response.session != null) {
//Get session
session = response.session;
//Set access token
accessToken = response.session.access_token;
//Call success callback
successCallback();
} else {
//Call failure callback
failureCallback();
}
});
}
});
When the user accepts permissions they get moved into a success callback method which is here (never makes it this far):
function acceptPermissions() {
//Code done before moving on
$('#submitInfo').submit();
}
Anyone see any issues?
That looks like it should work to me, so probably a good opportunity to file a bug report with Facebook....
That said, I think you could clean up your code using FB.login instead http://developers.facebook.com/docs/reference/javascript/FB.login/
FB.login(function(response){
if(response.session){
// logged in and connected user, carry on
session = response.session;
//Set access token
accessToken = response.session.access_token;
//Call success callback
successCallback();
}
else{
failureCallback();
}
}, {perms: permissionString});
So here's a question: do you have Flash installed? IE8, being the way it is, may be trying to load the Flash-based XD, and then failing silently. If you install Flash (and/or put in a catch for that), does it work?

Categories