Decoding Facebook's Signed Request in Ruby/Sinatra

Decoding Facebook's signed request in Ruby/Sinatra

I've run into this before. You just need to pad the end of the payload string with = marks until its length is divisible by 4.

This will work:

payload += '=' * (4 - payload.length.modulo(4))

(I'm not sure where/if this is documented by Facebook, but someone on IRC told me about it in early 2011, and sure enough, I've since found such padding in the source code of various Facebook client libraries)

Grab Facebook signed_request with Sinatra

The hint should be in your app crashing because there's nothing to decode.

I suspect the parameters get lost when redirecting. Think about it at the HTTP level:

  • The client posts to /tab with the signed_request in the params.
  • The app parses the signed_request and stores the result in instance variables.
  • The app redirects to /tab, i.e. sends a response with code 302 (or similar) and a Location header pointing to /tab. This completes the request/response cycle and the instance variables get discarded.
  • The client makes a new request: a GET to /tab. Because of the way redirects work, this will no longer have the params that were sent with the original POST.
  • The app tries to parse the signed_request param but crashes because no such param was sent.

The simplest solution would be to just render the template in response to the POST instead of redirecting.

If you really need to redirect, you need to carefully pass along the signed_request as query parameters in the redirect path. At least that's a solution I've used in the past. There may be simpler ways to solve this, or libraries that handle some of this for you.

Facebook Signed Request Partial Response

I'm using the Facebook PHP SDK to decode a signed request (provided by the JS SDK).

That means a signed_request you got from FB.login or FB.getLoginStatus, I suppose? You will only get the data that’s described here from one of those, https://developers.facebook.com/docs/reference/javascript/FB.getLoginStatus/

The other info you mentioned, page id, whether the user liked the page or not, etc., is only available in the signed_request that Facebook posts to your app on initial load.

Decode Signed Request Without Authentication

I am just pasting same answer I have answered in another post.

Fans-only content in facebook with asp.net C# sdk

You get signed request when your web page is loaded within facebook canvas app; you should be able to parse signed request something similar to following:

if (Request.Params["signed_request"] != null)
{
string payload = Request.Params["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);
var lPid = Convert.ToString(o.SelectToken("page.id")).Replace("\"", "");
var lLiked = Convert.ToString(o.SelectToken("page.liked")).Replace("\"", "");
var lUserId= Convert.ToString(o.SelectToken("user_id")).Replace("\"", "");
}

You need to add reference to json libraries in order to parse signed requestin C#, download from http://json.codeplex.com/

Also refere to How to decode OAuth 2.0 for Canvas signed_request in C#? if you are worndering about signed request.

Facebook graph API 2.1 signed request values

Its now against's Facebook's policy to gate access to an app or content within an app based on if the user has liked a page. See https://developers.facebook.com/policy

As part of this, they've removed the technical ability to determine if the user has liked the page when an app is rendered in a page tab.

How to parse JSON request body in Sinatra just once and expose it to all routes?

Use a sinatra before handler:

before do
request.body.rewind
@request_payload = JSON.parse request.body.read
end

this will expose it to the current request handler. If you want it exposed to all handlers, put it in a superclass and extend that class in your handlers.

sinatra-cors not responding with 200 when using middleware

The issue was related to an error in my middleware (Error module was not included in the source, and the default configuration of Rack caused errors not to be displayed)



Related Topics



Leave a reply



Submit