Using ASP.NET to read the Facebook signed_request object passed to iframe tabs

Facebook recently announced that they are phasing out FMBL in favour of iframe tabs for pages. This article discusses how to extract information from the signed_request parameter passed into the iframe using Json.NET LINQ to JSON.

Getting Started

Firstly, if you don’t already have one, create a new app using the Facebook developers app. Once your app is registered, select your app in the Developer app and click “Edit Settings”, then go to the “Facebook Integration” tab. In the “Page Tabs” section, give the name you’d like for your tab, make sure the type is set to “iframe”, then give the Tab URL. Secure and Edit URLs are optional.

Facebook Page Tabs Settings

Go back to the “My Apps” page in the Facebook developers app and select your app. Click to go to the Application Profile Page, then click “Add to My Page” and select your page from the resulting dialog. This whole process is covered in more detail on the Facebook developers documentation.

If you find yourself getting an IIS 405 error (“HTTP verb used to access this page is not allowed”) make sure you specify the full path to the page you’re looking for. For example, using Web Forms, http://mydomain.com/folder will usually render http://mydomain.com/folder/Default.aspx when accessed from the browser. However, since Facebook is POSTing to the url you gave, IIS throws an error.

Reading signed_request

Now onto the fun stuff. So it is written, Facebook makes a POST to your page, and in doing so sends a┬ásigned_request value. See the previous link for more detail, but in short, the value is a string made up of a signature, a period (“.”) and a Base64-encoded JSON object. We’re interested in that JSON object, so we extract it from the string, the convert it from Base64 to a JSON object.

string payload = Request.Form["signed_request"].Split('.')[1];
var encoding = new UTF8Encoding();
var decodedJson = payload.Replace("=", string.Empty).Replace('-', '+').Replace('_', '/');
var base64JsonArray = Convert.FromBase64String(decodedJson.PadRight(decodedJson.Length + (4 - decodedJson.Length % 4) % 4, '='));
var json = encoding.GetString(base64JsonArray);

Now we have a string containing the JSON object, we can use the Json.NET LINQ TO JSON functions to create a JObject containing the information:

var o = JObject.Parse(json);

Now we can query this object using SelectToken…

bool liked = (bool)o.SelectToken("page.liked");

…to extract information about the user, including whether or not they liked the page, their locale, and their age range. Facebook uses a range for ages to replace the fbml visibility tags.

Conculsion

Complete code:

using Newtonsoft.Json.Linq;
using System.Text;

public partial class Page_Default : System.Web.UI.Page
{
    protected string output = "";

    protected void Page_Load(object sender, EventArgs e)
    {
        output = "Whole thing:" +Request.Form["signed_request"];
        output += "Second part:" + Request.Form["signed_request"].Split('.')[1];

            try
            {
                string payload = Request.Form["signed_request"].Split('.')[1];
                var encoding = new UTF8Encoding();
                var decodedJson = payload.Replace("=", string.Empty).Replace('-', '+').Replace('_', '/');
                var base64JsonArray = Convert.FromBase64String(decodedJson.PadRight(decodedJson.Length + (4 - decodedJson.Length % 4) % 4, '='));
                var json = encoding.GetString(base64JsonArray);
                var o = JObject.Parse(json);

                output += "Decoded:" + json;

                bool liked = (bool)o.SelectToken("page.liked");

                output += "Liked:" + liked.ToString();
            }
            catch (Exception ex)
            {
                output += "Extract failed: " + ex.Message;
            }
    }
}

And this is the result:

Test Page Output

Part of the code in this article was adapted from this answer on Stack Overflow by Patrick Gidich.

This entry was posted in Blog and tagged , , , , . Bookmark the permalink.

Comments are closed.