Facebook FB.ui oauth popup on Canvas Page - javascript

I am trying to use the FB.ui oauth popup on a Facebook Canvas Page. I am using the latest Javascript SDK.
On a Page Tab, it works great to just do: FB.ui({method: 'oauth'}, callback); That gives me the allow access popup and then calls my callback with the response perfectly. No redirect is necessary.
However when I try the exact same thing on a Canvas, I get a FB dialog that says "An error occurred. Please try again later". Has anyone gotten it to work, or know of any workarounds?
I did have success with the top.location.href = "http://www.facebook.com/dialog/oauth?client_id=xxx&redirect_uri=xxx approach, but I would prefer to not have to redirect if possible.

It turns out that FB.login(callback) works fine on a canvas page, and it avoids the redirect as well.
So the answer for me was to just change the FB.ui to instead do FB.login. The response sent to the callback is slightly different from FB.ui, but very close.
FB.login(function(response) {
if(response && response.session) {
//do stuff with session
}
});

What does "it does not work" mean? The popup might be blocked if it's not called in reaction to a user event (like a a mouse click).

Related

How to get "Confirm form resubmission" when user trying to refresh browser

I have a page that doesn't allow user to refresh the page by clicking browser refresh button or pressing F5. So I want to simulate 'form resubmission' in order to show prompt message.
can someone guide me an approach to implement it?
Is there any cross-browser solution available for that?
To refresh without getting the prompt the page must have been fetched using HTTP GET
Make the form have method="GET" instead of method="POST" (and fix server processes to work with this change as apropriate)
Alternatively cache the post data in a session and redirect to the display page using HTTP code 303 immediately after form submission.
If you want to cause the prompt, make the link that takes the user to the page into a submit button on a POST form. if a user arrives with a GET request have serve them a page having javascript that submits a form converting the request into a POST request.
How did you manage to disable everything?
For the browser button, cross-compatible per MDN:
window.onbeforeunload = function() {
return "Data will be lost if you refresh the page. Are you sure?";
};
For the keystroke:
window.addEventListener("keyup", checkForRefresh, false);
var checkForRefresh = function(event) {
if (event.keyCode == 116) {
alert("Data will be lost if you refresh the page. Are you sure?");
}
};
The keystroke may need polyfill for IE8, but they provide it in the docs.
What you want is to listen for the beforeunload event and throw up a confirm box.
EDIT: Since you've stated in comments on another answer that you need to support Mobile Safari (which doesnt support beforeunload. You could try a library like jquery.AreYouSure
Per the discussion on this page, it supports Mobile Safari, though I havent used it myself
Note that some browsers will ignore the text you provide in the confirm call and show their default text instead. There are more in depth ways to get around that but this will prompt the dialog box.
$(window).on("beforeunload", function() {
return confirm("Do you really want to close?");
});
From other disccussion:
There are 2 approaches people used to take here:
Method 1: Use AJAX + Redirect
This way you post your form in the background using JQuery or something similar to Page2, while the user still sees page1 displayed. Upon successful posting, you redirect the browser to Page2.
Method 2: Post + Redirect to self
This is a common technique on forums. Form on Page1 posts the data to Page2, Page2 processes the data and does what needs to be done, and then it does a HTTP redirect on itself. This way the last "action" the browser remembers is a simple GET on page2, so the form is not being resubmitted upon F5.
You can refer this answer: https://stackoverflow.com/a/3968038/1853444

Twitter Web Intent on-close callback?

When a user clicks the twitter share button a web intent window is brought up on an already greyed out background (using an overlay). I am curious if there is a callback from the twitter web intent window to know when the window is closed or a tweet is submitted so that I can fade out the greyed out window once the user is done with the twitter intent window. Any help would be appreciated.
You can do something like this.
twttr.ready(function (twttr) {
twttr.events.bind('tweet', function (event) {
//do something
});
});
Using FirstDivision's answer, you can detect a successful tweet, but you will miss the case where the user closes the window without submitting a tweet.
According to this discussion thread, there is no official support for a failure event:
https://dev.twitter.com/discussions/17386
I am not sure if there is an acceptable work-around.

Cross Domain Pop Ups

My flow is as follows: the user clicks sign in on site 1. a pop up is opened from site 2 asking him to login using twitter. he then logs in - using oAuth, so the page changes. After a successful login the pop up should close and the code on site 1 should receive a notification.
What didn't work:
WebIntents - well, the examples on their site didn't even work, so I didn't try it locally..
easyXDM - communicates with an iframe, not a popup.
porthole - same, uses an iframe.
A horrible solution is refreshing the iframe every couple of seconds, to check if the user logged in already.
Is there a better way to do this? better libraries?
if you can refer the popup to another page after the user is logged in, you could use this:
main page:
localStorage.setItem('user_signed_in', false); // signed out by default
window.open("http://www.google.com/", "google_window", "menubar=no,resizable=no,scrollbars=no,status=no,width=400,height=300");
(function look_up() {
if(localStorage.getItem('user_signed_in')) {
go_on();
} else {
setTimeout(look_up, 500)
}
}());
function go_on() {
...
}
refer page:
localStorage.setItem('user_signed_in', true);
window.close();
Keep in mind that the refer page has to be on the same domain as your main page.
And, don't be afraid of bad support for localstorage in other browsers,
but if you really want to support oldies, you can use cookies, I believe.
When a user clicks a sign in button on site1 a pop up is opened from site2.
I'm assuming your using window.open thru an iframe to do this, and that you have already figured out how to bypass most browsers spam blockers etc.
Since you are opening this pop up as a new window, you are now in control of that window, and you can actually send stuff back from the new window.
This will be somewhat pseudo code, but just to make an example!
Lets say a user signs in with a link looking something like this:
<a href="" onclick="window.popup=window.open('/twitter/login.php', 'Twitter login', 'width=450,height=500'"</a>
Your pop up can now be refferenced by window.popup, and inside window.popup the original page is now called the window.opener.
On the same site that opens the popup you have a function, like this:
document.handleLogin = function (returnedDataFromPopup) {
console.log(returnedDataFromPopup);
}
After the user has logged in with oAuth, you need to redirect to a new page, this is explained in both the oAuth and Twitter guides, and you need to make that redirect happen inside the popup, and then capture the information from the login on that page and send it back to the original document and the handleLogin function.
Depending on what your using, in most PHP implentations you do something like this to get the data from the login, and this is of course after doing all the token and consumer key stuff:
$userinfo = $oAuth->getAttributes(); //or something similar, depends
So when redirecting from Twitter to a new page, the new page would look something like:
<? php
$userinfo = $oAuth->getAttributes();
?>
<script type="text/javascript">
window.opener.document.handleLogin(<?php echo json_encode($userinfo) ?>);
window.close();
</script>
This will actually run the handleLogin() function on the page that opened the popup, and it will send the userinfo from the popup to that function on the original page and then close the popup window.
I've used this technique with oAuth, OpenID, Google etc. and it works just fine without any need for local storage, cookies or page refresh at all, since you are in control of the popup window you can send information back and forth and you could even change the adress of the popup from the opening document on the fly if you wanted by doing something like this:
window.popup.location.href = 'google.com';
This is handy in some cases, for instance OpenID will by default close the popup and redirect the document.opener to the page specified, this is not what you want, and to overcome this you would have to open the popup on some random page, preferably an empty page that you control, and then redirect the popup's href to Twitter immediately after the popup is opened.
It all looks very complicated, but it is doable, and if you get this far, you now have the data, an all you have to do is somehow push it to site1 thru the iframe that holds site2. As pushing is'nt really possible without websockets or some sort of event driven server, like node.js, you will probably have to rely on long polling or something else, there are many ways to do this, and I'm sure you'll figure it out, but if you have some control over scripts running on site1, and you obviously have control over site2, then you can actually access some data thru an iframe with a little javascript, but I've never actually done that so I do not know exactly how it works.
It's not really relevant, but I don't really see why it would be useful for someone to login thru your site with an iframe from some other site, and it all seems strange to me, but thats up to you to figure out.

Facebook Logout Confusion

I have a strange problem, I have a logout link that displays only if the user is logged in. I have this code inside the the onclick event of this link (using a function):
FB.logout();
window.location = 'http://www.google.com';
If I click on this once, nothing happens, I know that the function gets executed because I've tested this with an alert. However, if I click on it a second time, the page reloads itself and the user is indeed logged out. The page is never directed to google.com, so the function never gets as far as the window.location part.
I have the window.location because I thought that if I could refresh the page using window.location.refresh once the logout is complete that it would successfully log the user out. However, if anybody has any other techniques on how to logout the user out of facebook, I would love to hear them! I've attempted to manually delete the cookie, but that didn't work, the cookie still existed for some reason. I've also tried this:
FB.logout(function(response) {
window.location = 'http://www.google.com';
});
I know a callback like this is possible because of the documentation:
http://developers.facebook.com/docs/reference/javascript/FB.logout
Has anybody else had this issue before? Any advice would help thanks!
UPDATE: After some debugging I've found out that if I click the link once. Then manually refresh the page it logs the user out.
From your description it looks to me that logout is working properly, but page refresh doesn't.
Try something like this maybe:
FB.logout(function(response) {
window.location.reload(true);
});
You might try putting an alert in the callback function to see if FB.logout is really completely successfully.
I was originally putting FB.logout directly in the onclick event of an anchor link and while that worked in FF and Chrome it did not work in IE or in my Android browser.
FF and Chrome will execute the FB.logout call quickly enough for this to work properly but that IE and mobile browsers (because of network speed in addition to differences in the JavaScript engine) will not complete the call successfully before the browser loads whatever page you're redirecting to.
I think I am trying to do the exact same thing you are doing and this code worked for me:
function mysignout(url)
{
FB.logout(function()
{
top.location.href = 'url';
});
}
Surprisingly, it take 2+ seconds for FB.logout to completely successfully in most environments. There is obviously some kind of ajax call involved to revoke authentication on the server, not just destroying the local cookie.

Facebook Connect Bug - JavaScript Refresh

Facebook Connect has a recent bug that is causing the permissions pop-up window to not close and refresh the parent window as it is designed to do. Instead, after approval by the user it attempts to load the page directly in the pop-up window which is an awful user experience and really hurting our registrations. You can see the bug by registering for our site using Facebook Connect: http://alltrails.com
The URL of the page after the user connects that Facebook Connect is incorrectly loading in the permissions pop-up window is of the form:
http://alltrails.com/?installed=1&session={"session_key":"2.Gu0duOqdElNjXRac5wnetw__.3600.1283799600-1486832834","uid":1486832834,"expires":1283799600,"secret":"tKFaEgBTF9RJeuQZfYUSCw__","base_domain":"alltrails.com","sig":"a8dd9f75418b530ae6c3d935e14274c4"}
I'm hoping that someone much better at JavaScript than myself could suggest a simple code snippet that we could add to our homepage that would only be invoked if the page URL includes '?installed=1' and would do the following to allow the same user experience as Facebook Connect was intended to provide:
Close the permissions pop-up window
Load the appropriate page http://alltrails.com/register/facebook in the original parent window
I've tried to do this a bunch of different ways but haven't had any luck with getting it to work correctly. Thanks in advance for your help!
It's a (unconfirmed) bug.
http://bugs.developers.facebook.net/show_bug.cgi?id=12260
Hopefully it gets more votes so it gets fixed - vote people!
In the meantime, i am (attempting) to employ the following 'creative workaround':
Add logic to my Default.aspx page to detect that URL they are redirecting to in the popup.
Redirect to my page, FacebookInboundAuthorization.aspx, preserving querystring.
On load of that page, register some JavaScript to close the popup and manually fire the "onlogin" event handler for my button.
EDIT - Another possible solution
So i do something like this for the "Disconnect from Facebook" button, which has a similar bug which has been in FBC from day 1. If the user is already logged in, and you click the "Disconnect from Facebook" button, the "onlogin" handler is not fired.
So what i ended up doing is replacing the Facebook Disconnect button with my own regular anchor tag, mimicing the Facebook CSS. This way i can have full control over the click event (fire the function i want).
So, this principle could (theoretically) be applied to this current bug.
That is, after you do FB.Init on client-side:
Check FB auth status using FB.Connect.ifUserConnected
If user is connected, hide the regular FB:Login button, and show your "fake" FB Login button. Copy across the "onlogin" function from your regular FB:Login button to your fake button as the onclick event.
Your Fake FB Login button would be a regular anchor tag, with the same CSS applied to the regular FB Login buton.
So essentially, if the user is already connected, we don't really need FB's intervention for authentication, we can just do whatever we want (request perms, redirect, etc).
That should work.
Unfortunately i have higher priority things i need to work on, but it sounds like this is top priority for you.
So give that a go, hope it helps.

Categories

Resources