在Ruby / Sinatra中解码Facebook签名的请求

由于Facebook贬低了新的FBML,我正在寻找一种新的方式来创建一个“揭示”标签(一个页面选项卡,向粉丝显示一个版本,向非粉丝显示另一个版本)。 Facebook已将数据添加到signed_request:

当用户在左侧菜单中选择您的应用程序时,该应用程序将接收带有一个附加参数页面的JMS数组的signed_request参数,该数组包含您的Tab所在的Facebook页面的“id”,布尔值(’ likes’)表示用户是否喜欢Page,还有一个布尔值(’admin’)表示用户是否是Page的’admin’以及用户信息数组。

我能够读取signed_request,但是我需要使用base64url解码来处理它以获得正确的JSON。 另外,我在研究中发现JSON格式不正确,因此需要在解码之前对其进行修改。 这是当前的代码(我现在只是在index.erb中打印已签名的请求):

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 

我正在努力保持应用程序尽可能轻,避免使用完整的Facebook库,因为这不是一个完整的应用程序(只是一个选项卡),不需要用户的任何其他权限。 我也欢迎任何关于我的风扇探测方法的建议。

我以前碰到过这个。 您只需要使用=标记填充有效负载字符串的末尾,直到其长度可被4整除。

这将有效:

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

(我不确定Facebook在哪里/是否有这些文件记录,但2011年初有人在IRC上告诉过我,当然,我已经在各种Facebook客户端库的源代码中找到了这样的填充)

我使用fbgraph库,它有工作parse_signed_request方法。

来自多愁善感的回答是正确的。 我只是遇到了同样的问题并用“=”填充它。

您可以使用以下方法validation这一点

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