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.

12 Comments

  1. Have you ever considered writing an e-book or guest authoring on other sites?
    I have a blog based on the same ideas you discuss
    and would love to have you share some stories/information.
    I know my viewers would enjoy your work. If you are even remotely
    interested, feel free to shoot me an email.

  2. Not sure how to implement this, I’m new to the Facebook API stuff. Hope you can help me out!
    I probably start with something like this: string urlFB = “https://graph.facebook.com/me” + “?access_token=” + token;

    It would be a lot easier if we could just use userInfo.name;

  3. how can we implement the same functionality for windows phone(winrt).I am facing issue with the session maintenance wherein even if the user is logged in to facebook app my app opens the login dialog.In short how can we check the login status of user and based on that skip the login dialog.
    your help would be much appreciated.
    thanks

  4. I think WebAuthenticationBroker is only supported in 8.1 phone applications. All apps are isolated from each other, so just because one app has authenticated, does not mean the other does not. It is up to Facesbook, not to you, to ensure that login dialog can just close without prompting for password.

Leave a Reply

Your email address will not be published. Required fields are marked *