Here I present the case:
I am developing an app that uses Facebook. We are using the Facebook API via js.
The user log into mobile browser (outside of app) to Facebook.
The user then comes into the app (the user already has authorized the app on Facebook some time ago).
Then the user goes to log in options, and chooses a button entitled "log whit facebook", its a simple button with a js action as follows:
$('#loginFacebookbBtn').on('vclick', function () {
FB.login(function (response) {
if (response.authResponse) {
FB.api('/me', function (response) {
... do something whit the response
});
} else {
}
}, {
scope: "email"
});
});
Then the Facebook API show a browser popup, that ask for user credentials. I put my credentials and then the browser popup go to a second page that said:
"you already authorized (APP NAME)" (Cancel) (OK)
When I press OK, this then goes to my app but I dont want that second page on popup browser...
Sorry for my English and thank you.
That's how it works - if the user isn't logged into Facebook already they need to log in - if the user was already logged into Facebook's app on the phone they wouldn't see that screen
Related
I'm registering users to my site via Facebook and have come across an issue on mobile. I'll start by saying i'm fairly new to the Facebook user login processes. The journey goes like so:
Firstly I call the fb.login function on click of a button to launch the facebook popup window for them to login like so:
jQuery(".welcome-cta-facebook span").on("click",function(){
FB.login(function(response) {
if (response.authResponse) {
getFbUserDetails();
} else {
console.log('User cancelled login or did not fully authorize.');
}
});
});
I then call the getFbUserDetails function once they have signed in and accepted the app like so:
function getFbUserDetails(){
FB.api(
'/me',
'GET',
{"fields":"id,name,picture{url},email"},
function(response) {
console.log(response);
fbParameters = "?facebookID=" + response.id + "&facebookName=" + response.name + "&facebookEmail=" + response.email + "&facebookProfilePictureURL=" + response.picture.url;
/* then send the fb parameters to my DB */
}
);
};
This journey works exactly as it should for desktop which is great but I encounter some problems with mobile which i'm unsure how to resolve:
if the user is not logged into their mobile browser I get the following error:
not logged in: You are not logged in. Please login and try again
if the user is logged in through their mobile browser I get the following error:
"URL Blocked: This redirect failed because the redirect URI is not
whitelisted in the app’s Client OAuth Settings. Make sure Client and
Web OAuth Login are on and add all your app domains as Valid OAuth
Redirect URIs."
Not sure why i'm seeing these errors if it works fine on desktop. How can I get a smooth journey for collecting someone's details on mobile? I am correct in using this approach? Worth noting I am NOT using a facebook login button.
Thanks and appreciate the help I can get!
You need to add all URI in whitelisted fied for you Facebook App
Facebook Developers -> Settings -> Advanced -> Security
In Security block you will see 'IP allowed server'
Add all URI in this field
I have a canvas facebook application which has both a web page and a designated mobile page.
The web page works fine and also when simulating the browser to mobile with the console everything works fine.
But, when I try to run the app from the facebook mobile app the canvas app loads (which is correct), but it does not login.
I am using the FB.login function.
login: function () {
var deferred = $q.defer();
FB.login(function (response) {
if (!response || response.error) {
deferred.reject('Error occured');
} else {
deferred.resolve(response);
}
}, {
scope: 'email, user_friends'
});
return deferred.promise;
},
and in the settings > advanced - I have the:
Client OAuth Login,Web OAuth Login, Embedded Browser OAuth Login,Valid OAuth redirect URIs and Login from Devices filled correctly.
but still from the facebook mobile app the canvas app does not preform the login.
I have been trying to get this to work all day.
and I cant find a solution anywhere.
I also cant debug the mobile facebook app.
any ideas how to approach this issue?
EDIT
Also looked at my Node server logs and I see that the FB.login is not even called.
EDIT 2
I ended up replacing the login with getLoginStatus which poses no problem to me since its a facebook canvas app... but the question still remains on how to do the login.
EDIT 3 11/26/2015
well so getLoginStatus did not completely solve my issue since it does not in fact log the user in so for the canvas games you probably need to login for the first entry if you need permissions... my solution was to add the login if the getLoginStatus returns not_autorized like so:
/**
* [getLoginStatus get the FB login status]
* #return {[type]} [description]
*/
getLoginStatus: function () {
var deferred = $q.defer();
FB.getLoginStatus(function (response) {
if (response.status === 'connected') {
deferred.resolve(response);
} else if (response.status === 'not_authorized') {
_fbFactory.login().then(function (fbLoginResponse) {
deferred.resolve(fbLoginResponse);
});
} else {
deferred.reject('Error occured');
}
});
return deferred.promise;
},
But wait, there is more... the FB.login function will not work well on mobile canvas games (not sure if its just not triggered or the browsers blog the popups or both). anyway you need to actively call it via button... so for mobile canvas games I had to add a start playing button and then the login does work..
EDIT 4 (Final)
eventually I noticed that FB.login() does not get triggered unless its an external event that triggers it, so I had to make a change for Mobile canvas where if the getLoginStatus doesnt return connected then I show a login button which does the login... the rest stayed the same.
what I did for mobile was similar to the accepted answer only to suit my needs...
I hope this helps someone besides me...
Make sure you're calling FB.login() with an event triggered by the user, such as an onclick on a button, as browsers can block potentially unsafe/dangerous javascript that's called directly. This is an extra layer of security for the end-user. There's 2 ways to create a login button:
Generate a login button with facebooks login button generator:
https://developers.facebook.com/docs/facebook-login/web/login-button
The generated login button will look similar to this:
<fb:login-button scope="public_profile,email" onlogin="checkLoginState();">
</fb:login-button>
Create your own html and use an onclick event to call FB.init():
<button onclick="FB.init()">Login</button>
Notes from the Facebook developers website:
As noted in the reference docs for this function, it results in a
popup window showing the Login dialog, and therefore should only be
invoked as a result of someone clicking an HTML button (so that the
popup isn't blocked by browsers).
https://developers.facebook.com/docs/facebook-login/web
Also, FB.getLoginStatus is the correct first step in logging in to check whether your user is logged into facebook and into your app.
There are a few steps that you will need to follow to integrate
Facebook Login into your web application, most of which are included
in the quickstart example at the top of this page. At a high level
those are:
Checking the login status to see if someone's already logged into your app. During this step, you also should check to see if someone
has previously logged into your app, but is not currently logged in.
If they are not logged in, invoke the login dialog and ask for a set of data permissions.
Verify their identity.
Store the resulting access token.
Make API calls.
Log out.
I see that your game doesn't require a login anymore, but maybe others will find this answer useful. :)
First of all: I'm aware that there's plenty of questions about the same topic, but none of them did the trick for me (I've already been like 3 days trying to get this working)...
I'm working on a Javascript mobile game which includes some FB functions (through the Javascript Facebook API). I'm having trouble while trying to really log out from Facebook to log in with another user: everytime I log out, I expect to call the log in function and prompt the FB login dialog where I can specify my e-mail and my password, but instead of this, Facebook logs in automatically with the last user without even asking me for anything... I'm using CocoonJS as the mobile platform and plain Javascript (no jQuery):
Log in function:
CocoonJS.Social.Facebook.init({
appId:<<MYAPPID>>,
channelUrl: "channel.html"
});
var socialService = CocoonJS.Social.Facebook.getSocialInterface();
socialService.login(function(loggedIn, error) {
if (error) {
console.error("login error: " + error.message);
}else if (loggedIn) {
console.log("login suceeded");
// Ask for extended permissions
CocoonJS.Social.Facebook.requestAdditionalPermissions("publish", "publish_actions",
function(response)
{
callback(response.error ? false : true);
}
);
CocoonJS.Social.Facebook.getLoginStatus(function(response) {
if (response.status === 'connected')
{
CocoonJS.Social.Facebook.api(
"/me",
function (response) {
if (response && !response.error) {
// Getting "me" returns the information of the "same" user!
console.log("User: "+response.first_name+" "+response.last_name);
}
}
);
}
});
}
});
Log out function:
CocoonJS.Social.Facebook.getLoginStatus(function(response) {
if (response.status === 'connected')
{
CocoonJS.Social.Facebook.logout(function(response) {
console.log("User logged out!");
});
}
});
The console log is thrown, so it seems that the user has actually logged out, but when I restart the game, a kind of "I'm doing something" screen appears for less than a second and the same user who logged out is logged in again (even throwing their personal information through calling "me")... I was expecting Facebook to ask me with which user I would like to log in to my app, but it doesn't...
I thing it has something to do with "session" or "cookies", but I don't know how to clear them through Javascript (and, as I'm using CocoonJS as the "browser", I have little control over it)... Any idea?
Thanks in advance for your time and effort! :)
CocoonJS uses native iOS and Android Facebook SDKs. The SDK itself takes care of the session storage, no cookies are used in CocoonJS.
Facebook SDK has two different methods to close the session:
close(): Closes the local in-memory session object, but does not clear the persisted token cache.
closeAndClearTokenInformation(): Closes the in-memory session, and clears any persisted cache related to the session
CocoonJS.Social.Facebook.logout calls internally to closeAndClearTokenInformation on Android and iOS. It erases all the cached tokens, so the next login starts from scratch.
Facebook SDK uses the Facebook Application to handle the login process if it's installed on the device, otherwise it fallbacks to a webview based login. The problem may be that you are testing on a device with the Facebook Application installed, so the SDK is able to get the logged in user from the Facebook App and doesn't need to ask for it again. If you logout from the Facebook Application or you test your app on a device with no Facebook App, Facebook will ask for a user and password.
I'm writing a webapp where users will need to login with Facebook (a Facebookless login does not make sense in the context of the app). Ideally, after their initial visit, when a user visits /index, my webapp sees a cookie it deposited earlier, and seamlessly logs the user in automatically and goes to the application (/app).
My problem arises when the user logs out of Facebook, and returns to my app. Since their cookie on my domain will still be present, and their oauth_token will still be valid (they are for 60 days now), I can still log the user in automatically, and the app will work as expected.
To me, it doesn't seem right that the app remains signed in with their Facebook account even when they are not signed in to Facebook. I played around on Stackoverflow itself; it allows this behaviour as well. Are my worries misplaced, or is there a recommended way to see if a user is signed into Facebook when they first request /index from my server.
In my opinion, I don't think your app should remain signed in while the user has already signed out of Facebook.
One scenario where this may not be desirable is: what if I am using your app from a public computer. After I logged out of Facebook, your app still "remembers" me. And now anyone who uses this computer will assume my Facebook identity inside your app.
I think the problem here is that you set your own cookie to remember the user's Facebook login status. Obviously, when user signes out of Facebook itself, your cookie is not cleared. So at this point your cookie is out of sync with Facebook status.
I recommend that you don't use your own cookie for the purpose of remembering user's Facebook login status. Always rely on Facebook itself for this purpose.
The general strategy is, whenever user comes to your app, you should check the Facebook login status by using the mechanism provided by Facebook. This way, your app will be in syn with Facebook in terms of user's login status.
I personally use this piece of code to call Facebook Javascript API for the purpose of user login:
/*
* Init code for Facebook connect
*/
window.fbAsyncInit = function() {
FB.init({
appId : FACEBOOK_APP_ID, // App ID
channelUrl : CHANNEL_URL, // Channel File
status : true, // check login status
cookie : true, // enable cookies to allow the server to access the session
xfbml : true, // parse XFBML
oauth : true
});
// check facebook login status
FB.getLoginStatus(function(response) {
console.log("FB login status: " + response.status);
if (response.status === 'connected') {
showWelcome(); //display welcome message
} else if (response.status === 'not_authorized') {
// the user is logged in to Facebook, but not connected to the app
showFbLogin(); //display Facebook Login button
} else {
// the user isn't even logged in to Facebook.
showFbLogin(); //display Facebook Login button
}
});
// subscribe to facebook events
FB.Event.subscribe('auth.authResponseChange', function(response) {
fbAuthResponseChanged(response);
});
};
I have some troubles when using javascript code for Facebook invite friends. Details:
User Facebook A already authorized our web application, and give us the permission to offline-access their access tokens.
User A logged in into our web. The system detect that A synchronized his account (on our web) with Facebook, so it retrieve A's information from Facebook.
In the same browser, A open a new tab, and log out of Facebook.
A user B borrows A computer, and then logged in Facebook but with his account: user Facebook B.
He move to our web (the tab that A already opened), and click "Invite friends". The list show all the friends of user B, not user A.
This scenario (though very rarely happens), troubled our group testers, because it may causes un-expected behavior for our web application (a user may think he synchronize the wrong Facebook account).
To stop that case, I want to differentiate who is currently logged-in Facebook (user B), with the user has authorized our application (user A). Currently I'm checking like this:
function showInvitationDialog() {
FB.init({
appId:'${appId}',
cookie: false,
status: true,
xfbml: true
});
FB.getLoginStatus(function (response) {
if (response.session) {
if (response.session.uid != ${fbId}) {
alert("You are currently logged in to FB with another account (different to the account you registered). Please make sure that you don't accidently use others FB account to invite");
return;
}
}
var request_ids = FB.ui({ method: 'apprequests',
message: '<#spring.message code="friends.invitation.message" />',
data: 'hello'});
});
}
The above code works for most case, but it have a problem:
If user X is logged in Facebook user X', and he authorize our app already: response.session.uid = X_FacebookId -> ok, we know who he is
If user X is not logged to Facebook, response.session == undefined
If user X is logged in with Facebook user X', and he hasn't auhthorized our application yet, response.session == undefined
So I can not differentiate the case 2 vs case 3. In both case, the results from getLoginStatus is the same, but I want to solve it differently:
case 2 -> continue to call the function to let "Login dialog" popup
case 3 -> informs the user that he has logged into the wrong Facebook
account.
Is there any solution for this situation? Any idea will be greatly appreciated.
getLoginStatus() returns a Json object which is like :
{
status: one of 'not_authorized' / 'connected' / 'unknown'
authResponse: ....
}
not_authorized means they are logged into facebook but haven't authorized your app,
connected means they have authorized the app,
unknown means they are not logged into facebook.
(from memory so might not be exact)
Also, you might want to consider listening for auth events, which might make this problem easier. http://developers.facebook.com/docs/reference/javascript/FB.Event.subscribe/