Facebook Authentication before showing page - javascript

I trying to use facebook authentication in my ember.js app. If the use already have session with facebook (he already have opened facebook in another tab) and he visits my page, first login screen is shown for a moment and as soon as application gets response from facebook, user is redirected to Welcome page.
If user already have facebook session, How can I wait for facebook response and based on response decide to show my html.
In other words, I want to execute my javascript code before rendering the page. I am using following library for facebook authentication
http://luansantos.com/2012/03/06/using-facebook-js-sdk-with-emberjs/

Use deferReadiness method
for ember-facebook it could look like this (not tested):
App = Em.Application.create(Em.Facebook);
App.deferReadiness();
App.set('appId', 'YourAppId');
App.addObserver("/auth-token", function(sender, key, value) {
if(value == false) {
App.advanceReadiness();
}
});

Related

How to authorise user for a web page in FB messenger, without logging in?

I am building a chat bot in FB messenger that saves user profile data, food and calorie consumption. I am using Node/Express/MongoDB for the backend and want the user to be able to open a personal dashboard page inside the chat with a link. So that URL would be something like www.myapp.com/:id where :id is a personal key.
The problem I have is how can only the user belonging to this page and data open this without having to login? Normally you would go to a website, login and be able to see the page, but this not a step I want in a chat bot. I want the user just to open the page in the chat, whether that is results in opening a browser tab or a native webview. Any advice on how I can achieve this?
To verify if the user on the page is the facebook user you intend the page to be for, add FB Messenger Extensions to the page.
When clicking a webview in your bot, Messenger extensions will be able to tell who they are logged in as, and allow you to do whatever you want with that info. In your case, checking if the userid matches the one passed by your bot in the url. There are many ways to check this, like splitting query strings, but I stuck with the example route in your question.
Use the following on your dashboard page. The below will check with FB who the logged in user is, and if it doesn't match the ID of the link they followed, deny them access with a redirect.
<script>
MessengerExtensions.getContext(<YOUR-APP-ID>,
function success(thread_context){
// User ID was successfully obtained.
var psid = thread_context.psid;
// Grab the user id from your url (assumes your url is /<USER_ID>)
var loc = window.location.pathname.replace(/^\/|\/$/g, '');
if (psid !=== loc) {
window.location.replace("http://YOUR_DOMAIN.com/error")
}
}, function error(err, errorMessage) {
// Error handling code
});
</script>
Docs on getting user id with Messenger Extensions
Try this:
Open Messenger, then open DevsConsole and go to Network tab. Now paste your link and click it. In the Network tab open the request details issued by the click. Under "Form Data" you should see this:
q:[{"user":<your_fb_id>,...
You can use this id to authenticate the user in your app - just couple it somehow with the authorized user in your app. This is just the first idea off the top of my head, it should be quite safe if you mix it e.g. with CORS security headers.

Spring Social - How to Redirect to original URL or authenticate via Popup/Iframe with reload

I have a web application which uses spring security with spring social integration. I have placed sign-in button (form post) on the menu of the application which can be accessed from any of the paths/webpages. I am able to sign-in by posting on /signin/{provider} from my webpage which redirects to google's login page for authentication and upon successful authentication redirects back to a "configured URL". I want this URL to be dynamic so the user is redirected back to original URL where the user clicked on Sign In With Google button.
Options I have:
Use SignInAdapter to return the URL to be redirected to. We get the native web request object here in signIn() method but I am not able to find a way to send some parameter say, callback url, during initial signin form post which may become available in signIn() method.
Upon FormPost, instead of redirecting in the same window, open an iframe/popup to handle the post response (which is actually the providers url like http://accounts.google.com/......). And after successful authentication reload the parent page. But here iframe does not allow cross domain urls. For popups, I don't know how to bring form post response in a popup.
This is an e-commerce application so want to strive for some best practices in terms of security and users constraints (like blocked popus).
Finally got it working with second approach mentioned in the question. Instead of doing sign in form post (signin/{providerId}) directly on click of "Login with Google" button, open a popup window (child window) with something like :
<button type="submit" onClick=
"window.open('/signin?formId=googleForm','Ratting','width=550,height=400,left=150,top=200,toolbar=0,status=0,');" class="googlelogin" style="border-width: 0px;">
</button>
and on this popup window, through javascript, do an auto form post during onload.
Configure the redirect url, which loads after succesful signin, to a page which has a javascript code which reloads your parent window. Something like:
(function(){
if (opener) {
opener.postMessage("reload", '*');
window.close();
}
else {
window.location.assign('/');
}
}());
The parent window should have a listener for message posted by child window. Something like:
function listener(event){
if (event.data === "reload")
document.location.reload();
}
if (window.addEventListener){
addEventListener("message", listener, false)
} else {
attachEvent("onmessage", listener)
}
Hope it helps someone looking for the solution to a very trivial use case like this.

Facebook Canvas, Unable to login from facebook on mobile devices

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. :)

Check if user posted (or cancelled) sharing to Facebook in Share Dialog using FB.ui

I'm using a share dialog and I want something to occur after the user posts something to his/her timeline. Right now I'm using:
function shareToFB(myName, myLink) {
$('.overlay-bg').hide();
FB.ui({
method: 'share',
href: myLink,
name: myName
}, function(response) {
if (response && !response.error_code) {
alert("Something");
} else {
alert("Error");
}
}
);
}
But this causes "Something" to show up even when the user cancels posting. Is there any way I can find if the user has posted the message to his/her timeline without requiring any permissions. I won't mind if this requires me to use a different method of sharing (like a feed dialog).
Use Feed Dialog instead.
Despite its UI being ugly, successful sharing via Feed Dialog will return a response object like {post_id: "10206702999763274_10206703017843726"} regardless of user authenticating your Facebook app or not, while pressing cancel will return a null and closing popup will return undefined.
You can test this behaviour by going to your normal Facebook user profile settings and try removing your app from allowed list.
This is in contrast to the Share Dialog, which, if your app has not been authenticated by user, will return an empty response object {} regardless of successful sharing or not.
Furthermore, if you use the direct url redirect method instead of js SDK, when the user press cancel on the share page you will receive a GET parameter error_code and error_message appended to your redirect target.
[From December 2015] => Use Feed Dialog or the Share Dialog to access the post ID in the response. To achieve this the user must have logged into your app and granted it publish_actions. https://developers.facebook.com/docs/sharing/reference/share-dialog#response
NOTE: This is true for the time of this writing (API v2.3). However as Facebook is notorious for breaking API behaviour, you should test it yourself first.
According to the docs, the response is the object_id of the posted entry - and it is only filled if the user authorized the App. Meaning, you canĀ“t detect if a user really posted something if the user is not authorized.
Source: https://developers.facebook.com/docs/sharing/reference/share-dialog

Make Facebook permission window modal

I'm using the standard code from Facebook JS SDK in order to get the permissions for an application (this is an example with email permission):
FB.login(function(response) {
if (!response.authResponse) {
//user refused to grant permissions, redirect to the 'index' page
window.location = "/";
}
}, {scope:"email"});
When the user tries to get into the application's page (the function above is on page load), the permission request window pops-up, but it can be moved or even put in icon, while the user can still view the page. Is there any mean that I can assign the permission request window as a modal one?
You can get the user to login using the getLoginUrl() function in the PHP SDK. This redirects the user to a complete Facebook Login page and then have it redirect back to your app once complete.
E.g. https://www.facebook.com/dialog/oauth?client_id={app_id}&redirect_uri={redirect_url}

Categories