开发者

Decoding Facebook's signed request in Ruby/Sinatra

Due to Facebook deprecating new FBML, I'm looking for a new way to create a "reveal" tab (a page tab that shows one version to fans and another to non-fans). Facebook has added data to the signed_request:

When a user selects your app in the left-hand menu, the app will receive the signed_request parameter with one additional parameter, page, a JSON array which contains the ‘id’ of the Facebook Page your Tab is hosted within, a boolean (‘liked’) indicatin开发者_JAVA技巧g whether or not a user has liked the Page, and a boolean (‘admin’) indicating whether or not the user is an ‘admin’ of the Page along with the user info array.

I'm able to read the signed_request fine, but then I need to process it with base64url decoding to get the correct JSON. Additionally, I've found in my research that the JSON is improperly formatted for Ruby so needs to be modified prior to decoding it. Here's the current code (I'm just printing the signed request in index.erb for now):

helpers do
  def base64_url_decode str
    encoded_str = str.gsub('-','+').gsub('_','/')
    encoded_str += '=' while !(encoded_str.size % 4).zero?
    Base64.decode64(encoded_str)
  end

  def decode_data str
    encoded_sig, payload = str.split('.')
    data = ActiveSupport::JSON.decode base64_url_decode(payload)
  end
end

get '/' do
  signed_request = params[:signed_request]
  @signed_request = decode_data(signed_request)
  erb :index
end

I'm trying to keep the application as light as possible and avoid using a full Facebook library as this won't be a full application (just a tab) and won't require any additional permissions from users. Any recommendations as to my method for detecting fans are welcome as well.


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)


I use fbgraph library which has working parse_signed_request method.


The answer from dorkitude was correct. I just had the same issue and padding it with a "=" worked.

You can verify this by using:

Base64.strict_decode64( invalid_payload )
=> ArgumentError: invalid base64
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜