Apr
22
2011

 

You can try the example for this guide at: http://www.permadi.com/tutorial/facebook-js-oauth-popup-centered/index.html

Background

The normal way to open the OAUTH dialog is as described here, by calling:

[c]

https://graph.facebook.com/oauth/authorize?client_id=APP_ID&scope=publish_stream&redirect_uri=http://www.example.com/url/;

[/c]

You can open the dialog in the same window, like this:

[c]
top.location = 'https://graph.facebook.com/oauth/authorize?client_id=APP_ID&scope=publish_stream&redirect_uri=http://www.example.com/url/';
[/c]

More details can be read here.  

The normal route if you want to show the dialog as a popup is to use FB.login() (also described here).  The problem with the FB.login dialog is that there is no way to control the location of the dialog, and most often than not, it appears off center.  A little known fact is that the OAUTH page accepts a display parameter, as described at http://developers.facebook.com/docs/reference/dialogs/oauth/. You can also open the OAUTH with display=popup to make it a popup like this:

[c]
window.open('https://graph.facebook.com/oauth/authorize?
    client_id=APP_ID&scope=publish_stream&redirect_uri=http://www.example.com/url/&display=popup', 
    "loginWindow");
[/c]

But there’s a problem with this in that once the used is logged in, the dialog will not issue a callback to the application and instead, it will open the redirect_uri in the popup window.  

So here’s our strategy to counter that.

1. In the main app page, use window.open() to open the OAUTH dialog.

2. For the redirect_uri, create a dummy page.  This page should be set as the redirect_uri  (so that this page, instead of your app, will be opened in the popup).

3. In the dummy redirect_uri page, issue a Javascript command to close itself.

4. In the app, use a timer to check whether the popup window has closed or not.  

Let’s do those one at a time:

1. Write a function that will be called when user attempts to login.

For example, like this:

[c]
var facebookLoginWindow;
var loginWindowTimer;
function facebookLogin()
{
	var popupWidth=500;
	var popupHeight=300;
	var xPosition=($(window).width()-popupWidth)/2;
	var yPosition=($(window).height()-popupHeight)/2;
	var loginUrl="http://www.facebook.com/dialog/oauth/?"+
		"scope=publish_stream&"+
		"client_id="+APP_ID+"&"+
		"redirect_uri=http://www.permadi.com/tutorial/facebook-js-oauth-popup-centered/loginHandler.html&"+
		"response_type=token&"+
		"display=popup";
	
	facebookLoginWindow=window.open(loginUrl, "LoginWindow", 
		"location=1,scrollbars=1,"+
		"width="+popupWidth+",height="+popupHeight+","+
		"left="+xPosition+",top="+yPosition);
		
	loginWindowTimer=setInterval(onTimerCallbackToCheckLoginWindowClosure, 1000);
}


[/c]

I won’t discuss the initialization process here but you can read about it here: http://www.permadi.com/blog/2010/11/facebook-open-graph-api-authenticating-in-iframe-applications/

What this does is to open the authorization window (as described here) in a popup, centering it using xPosition and yPosition.  The redirect_uri is a dummy html page, named loginHandler.html (described more in Step 2 below).  

I am using jQuery to get the window dimensions ($(window).width() and $(window).height()) but you can use regular JavaScript for this.

Then I am centering the position based on the popup dimensions.  Note that this popup dimensions is based on experimentation and if your application require a lot of permissions, the height of the windows might not be enough to hold all the paragraph — so make sure to test.

2. Create a dummy page.

 
This page should be set as the redirect_uri (so that it will be opened in the popup). This URL must be within your application URL.  Ie: within http://www.permadi.com in my example below:

3. In the dummy redirect_uri page, issue a Javascript command to close itself.

Here’s my dummy redirect_uri page , the loginHandler.html refered in Step 1.

[c]
<html>
  <head>
    <script>
	window.close();
    </script>
  </head>
<body>
</body>
</html>
[/c]

4. In the main app, use a timer to check whether the popup window has closed or not.  

If the window has closed, then call FB.init again to get the logged-in user session.   Note that there’s a bonus for this in that you can still maintain the state of the application in this way. (Observant reader might suggest todetect the window closing by attaching onClose event handler to the window, but this does not work.)

In the example code, the timer is started in Step 1, withtin the facebookLogin() function, in this line:

[c]
loginWindowTimer=setInterval(onTimerCallbackToCheckLoginWindowClosure, 1000);
[/c]

And here’s the callback, which I call onTimerCallbackToCheckLoginWindowClosure. It simply checks if the window is closed, and if it is, then we issue another FB.init to get the user session.

[c]
function onTimerCallbackToCheckLoginWindowClosure() 
{
	// If the window is closed, then reinit Facebook 
	if (facebookLoginWindow.closed) 
	{
		clearInterval(loginWindowTimer);
		FB.init({
		  appId  : APP_ID,
		  status : true, // check login status
		  cookie : true, // enable cookies to allow the server to access the session
		  xfbml  : true  // parse XFBML
		});

		FB.getLoginStatus(onFacebookLoginStatus);			
	}
}
[/c]

Yes there’s something hacky in this, but it is not so hack-ish and there’s nothing esoteric about it.   

Example

You can try the example at: http://www.permadi.com/tutorial/facebook-js-oauth-popup-centered/index.html

Leave a Reply

*