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


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

当用户在中选择您的应用时   左侧菜单,应用程序将收到   signed_request参数有一个   附加参数,页面,JSON   包含的'id'的数组   Facebook页面是您的标签托管   在一个布尔('喜欢')指示   用户是否喜欢   页面和布尔值('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库,因为这不是一个完整的应用程序(只是一个选项卡),不需要用户的任何其他权限。我也欢迎任何关于我的风扇探测方法的建议。


11407
2018-02-14 00:03


起源



答案:


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

这将有效:

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

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


7
2018-02-14 00:55



这似乎很接近,但不正确。您只想填充1或2个字符,而不是3或4。如果payload.module(4)为零,则不填充。 en.wikipedia.org/wiki/Base64 - Felix Livni
注意:如果使用strict_decode64或urlsafe_decode64,则使用四个'='的填充似乎会中断,但decode64可以容忍。 - Felix Livni


答案:


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

这将有效:

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

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


7
2018-02-14 00:55



这似乎很接近,但不正确。您只想填充1或2个字符,而不是3或4。如果payload.module(4)为零,则不填充。 en.wikipedia.org/wiki/Base64 - Felix Livni
注意:如果使用strict_decode64或urlsafe_decode64,则使用四个'='的填充似乎会中断,但decode64可以容忍。 - Felix Livni


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


6
2018-02-17 20:36



工作得很完美,tnx - Mike Bevz


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

您可以使用以下方法验证这一点

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

2
2018-06-21 17:15