Wednesday, 2 May 2012

Loging into your website with Facebook



Facebook allows you to use it's authentication mechanism to sign-in to your own website, but through Facebook. This means that users are more likely to sign up to your website that if they had to fill in a huge registration form. Some figure suggest a 40% increase! My registration process isn't that bad - I'm using Community Builder (CB-Login) but I thought it'd be nice to give people an option.

The Facebook Developers page has all the info:


http://developers.facebook.com/docs/guides/web/

Facebook uses OAuth 2.0 for authentication and authorization. You can add login to your site using OAuth 2.0 directly (Facebook's Authentication Overview is here), they recommend the open source JavaScript SDK as the simplest way to use Facebook for login. I've used OAuth 2.0 for authentication on Android devices before, it's standard stuff. However, I'd like to use JavaScript because then I can use the values I get from Facebook and use them to pre-populate my registration fields. Although the Facebook login will help, I would like people to fill in more info if they can. Plus it's a good first step in getting this thing working.


I found I had quite a few apps in there already. They're from my websites I think, though I've never seen this page before (maybe I have - I just have a really bad memory). Here's my new app:


 


Then you fill out a security check before being presented with your new app:




The appId that is given to you is a unique identifier for your site that ensures the right level of security between the user and your website. Fill out the Basic settings as best you can, especially the App Domain.

You must have a file on your domain! I haven't finished my Joomla! site yet so I just put up this index.html file:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>My Website</title>
</head>
<body>
<h1>Welcome to My Website</h1>
<p>This is going to be a super website!</p>
</body>
</html>


You also need a channel.html file:

<script src="//connect.facebook.net/en_US/all.js"></script>

You can then use this in a little bit of JavaScript to pull in the "Login with Facebook" button. Here is my loginwithfb.html file:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>My Facebook Login Page</title>
</head>
<body>
    <div id="fb-root"></div>
    <script>
      // 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));

      // Init the SDK upon load
      window.fbAsyncInit = function() {
        FB.init({
          appId      : '[YOUR APP ID', // App ID              
          channelUrl : 'channel', // Path to your Channel File
          status     : true, // check login status
          cookie     : true, // enable cookies to allow the server to access the session
          xfbml      : true  // parse XFBML
        });

        // listen for and handle auth.statusChange events
        FB.Event.subscribe('auth.statusChange', function(response) {
          if (response.authResponse) {
            // user has auth'd your app and is logged into Facebook
            FB.api('/me', function(me){
              if (me.name) {
                document.getElementById('auth-displayname').innerHTML = me.name;
              }
            })
            document.getElementById('auth-loggedout').style.display = 'none';
            document.getElementById('auth-loggedin').style.display = 'block';
          } else {
            // user has not auth'd your app, or is not logged into Facebook
            document.getElementById('auth-loggedout').style.display = 'block';
            document.getElementById('auth-loggedin').style.display = 'none';
          }
        });


        // respond to clicks on the login and logout links
        document.getElementById('auth-loginlink').addEventListener('click', function(){
          FB.login();
        });
        document.getElementById('auth-logoutlink').addEventListener('click', function(){
          FB.logout();
        });
      }
    </script>

    <h1>Facebook Client-side Authentication Example</h1>
      <div id="auth-status">
        <div id="auth-loggedout">
          <a href="#" id="auth-loginlink">Login</a>
        </div>
        <div id="auth-loggedin" style="display:none">
          Welcome to, <span id="auth-displayname"></span> 
        (<a href="#" id="auth-logoutlink">logout</a>)
      </div>
    </div>

  </body>
</html>




Here's the final result:




Press the login button and you get the Facebook login authorisation form, thereafter you get the Facebook sign-in dialogue. Here's the example from Facebook's documentation:





When you click, Allow, it returns to the same web-page.




Now a lot more work is needed to get this looking slick, and posting to the user's News Feed. Here's how to get a button:

<h1>Facebook Client-side Authentication Example</h1>
      <div id="auth-status">
        <div id="auth-loggedout">
            <div class="fb-login-button">Login with Facebook</div>
            <!--<a href="#" id="auth-loginlink">Login</a>-->
        </div>
        <div id="auth-loggedin" style="display:none">
          Welcome to My Website, <span id="auth-displayname"></span> 
        (<a href="#" id="auth-logoutlink">logout</a>)
      </div>
    </div>