Posts Tagged Facebook
How to Validate a Facebook Canvas Page
Posted by Jayson in Technology on 2010-08-25
Facebook has good documentation on how to authenticate a request to your canvas page. You can find that documentation here.
However, if you’re developing your page in ASP.NET (WebForms or MVC), there’s a few things in the documentation that may throw you off. The remainder of this post assumes you’re developing a Facebook application in ASP.NET MVC and your Facebook application is set as iFrame (for authentication).
When your application is set as iFrame, the Facebook parameters are contained in the request parameters (and not in cookies as you may be lead to believe from the use of the keyword in the documentation). The purpose of validating a canvas page, is to ensure that the request IS coming from Facebook. Therefore, Facebook has computed a hash value (called a signature) with all the (Facebook) parameters + your application’s secret key. So, in order to verify, you just have to perform the same computation and compare your computed signature with Facebook’s. This works because only you and Facebook should know your application’s secret key.
Here’s a snippet of code that you can use to perform that verification:
public static bool IsRequestValid(string applicationSecretKey, HttpRequestBase request) { bool valid = false; string originalSignature = request.Params["fb_sig"]; if (!string.IsNullOrWhiteSpace(originalSignature)) { // Step 1: Generate an input string // i - Order all "facebook" parameters alphabetically // ii - Remove the preceeding 'fb_sig_' characters // iii - Concantenate them all string input = string.Join("", from p in request.Params.Cast<string>() where p.StartsWith("fb_sig_") orderby p ascending select p.Remove(0, 7) + "=" + request.Params[p]); // Step 2: Append the application's secret key input += applicationSecretKey; // Step 3: Compute a signature // i - Compute an MD5 hash with the generated string // ii - Convert the hash into hexadecimal and concantenate them var data = HashAlgorithm.Create("MD5").ComputeHash(Encoding.ASCII.GetBytes(input)); string computedSignature = string.Join("", from d in data select d.ToString("x2")); // Step 4: Compare with the orignal signature if (computedSignature == originalSignature) { valid = true; } } return valid; }
This uses LINQ quite heavily and also uses String.Join in favor of String.Concat or StringBuilder because of the reported performance advantage the Join method has over the other ones.
Happy Coding!