Implementing Facebook Integration in WinRT App

I am working on and off on a personal application for Windows 8.  I would like to protect the data via a login screen, but I would really hate for the user to remember yet one more login.  Moreover, I would like to at some point generate email reminders for the users as well as enable data sharing between users of the app.  As a result, I wanted to use Facebook login, assuming that most people out there already have an account.

Upon research I wanted to use WebAuthenticationBroker because this class makes it much easier to integrate with authentication providers, such as Facebook.

First things first, you have to create an application with Facebook.  Head over to https://developers.facebook.com/apps and click on Create New App.  Give it a name and save.  Then make sure to head over to Edit App and set up Basic Information, such as meaningful name.  Then check out Advanced tab and flag your app as Native.  Because user email is all I need, I also only specify that permission in Permissions tab for my app on Facebook.That is it.  Now just write down App ID, you will need it soon.

Now, it is time to create Windows Store application.  Once that is done, you are ready to get started with WebAuthenticationBroker.  First of all, you need to create request URL.  You will not be asking the user for any information at this point.  We need two different URLs to work with Facebook via broker: Facebook URL for login and callback Uri.  Since we are writing a desktop app, we can hard-code callback URL.  Of course, you need to define your appId variable – the same one you saw on Facebook when creating your app.

var callbackUrl = "https://www.facebook.com/connect/login_success.html";

Our login Uri is simple, and does include callback Uri as well

 

var url = "https://www.facebook.com/dialog/oauth?client_id=" + appId +
            "&redirect_uri=https://www.facebook.com/connect/login_success.html" + 
            "&scope=email&display=popup&response_type=token";

Now, we are ready to create authentication request

var webAuthenticationResult =
    await WebAuthenticationBroker.AuthenticateAsync(
            WebAuthenticationOptions.None,
            new Uri(url),
            new Uri(callbackUrl));

As you can see, I am using await keyword, so you much flag the routine that calls this code with async keyword.

Now, I need to get the token that Facebook API returns to make additional call to get user email address.  I will use HttpClient for that, and I just need to parse out the token from return value as  follows.  Here is entire code the routine.

try
{
    var appId = "XXXXXXXXXXXX";
    var callbackUrl = "https://www.facebook.com/connect/login_success.html";
    var url = "https://www.facebook.com/dialog/oauth?client_id=" + appId +
                "&redirect_uri=https://www.facebook.com/connect/login_success.html" +
                "&scope=email&display=popup&response_type=token";


    var webAuthenticationResult =
        await WebAuthenticationBroker.AuthenticateAsync(
                WebAuthenticationOptions.None,
                new Uri(url),
                new Uri(callbackUrl));
    if (webAuthenticationResult.ResponseStatus == WebAuthenticationStatus.Success)
    {
        var client = new HttpClient();
        var indexOfToken = (webAuthenticationResult.ResponseData.IndexOf(
            "access_token", StringComparison.Ordinal) + 13);
        var tokenString = webAuthenticationResult.ResponseData.Substring(indexOfToken);
        var token = tokenString.Substring(0, tokenString.IndexOf("&", System.StringComparison.Ordinal));

        var data = await client.GetStringAsync(
                @"https://graph.facebook.com/me?fields=email&format=json&access_token=" + token);
        var serializer = new DataContractJsonSerializer(typeof(UserInfo));
        UserInfo userInfo;
        using (Stream stream = new MemoryStream(Encoding.UTF8.GetBytes(data)))
        {
            userInfo = (UserInfo)serializer.ReadObject(stream);
        }
        var dialog = new MessageDialog(userInfo.email + " " + userInfo.id);
        dialog.ShowAsync();
    }
    else
    {
        var dialog = new MessageDialog("Error occurred.  Please check your internet connection and credentials.");
        dialog.ShowAsync();
    }
}
catch (Exception)
{
    var dialog = new MessageDialog("Error occurred.  Please check your internet connection and credentials.");
    dialog.ShowAsync();
}

UserInfo class is super simple, and just used for deserialization.

    public class UserInfo
    {
        public string email { get; set; }
        public string id { get; set; }
    }

That is all there is to it.  With this code you can login and get user email.  Because user email is all I need, I specify this as a parameter to login request.  I also only specify that permission in Permissions tab for my app on Facebook.

Enjoy.