与Sinatra一起获得Facebook signed_request

时间:2012-02-08 20:05:16

标签: ruby facebook facebook-graph-api facebook-like sinatra

我试图弄清楚用户是否喜欢我们的品牌页面。基于此,我们希望显示一个类似按钮或一些“谢谢你”#39;文本。

我正在使用heroku上托管的sinatra应用程序。

我尝试了这个帖子中的代码:Decoding Facebook's signed request in Ruby/Sinatra

然而,它似乎没有抓住signed_request,我无法弄清楚原因。

我有以下方法:

get "/tab" do
  @encoded_request = params[:signed_request]
  @json_request = decode_data(@encoded_request)
  @signed_request = Crack::JSON.parse(@json_request)
  erb :index
end

# used by Canvas apps - redirect the POST to be a regular GET
post "/tab" do
  @encoded_request = params[:signed_request]
  @json_request = decode_data(@encoded_request)
  @signed_request = Crack::JSON.parse(@json_request)
  redirect '/tab'
end

我也有来自该主题的帮助消息,因为它们似乎对我有意义:

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

  def decode_data(signed_request)
    payload = signed_request.split('.')
    data = base64_url_decode(payload)
  end
end

然而,当我做的时候

@encoded_request = params[:signed_request]

并在我的视图中阅读:

<%= @encoded_request %>

我一无所获。

这不应该至少回归吗?我的应用似乎崩溃了,因为没有什么可以解码的。

我似乎无法在互联网上找到很多有关此内容的信息,所以如果有人能帮助我,我会很高兴。

有没有更好的方法来了解用户是否喜欢我们的网页?或者,这是要走的路,我只是忽略了一些明显的东西?

谢谢!

1 个答案:

答案 0 :(得分:2)

提示应该在您的应用程序崩溃中,因为无需解码。

我怀疑重定向时参数会丢失。在HTTP级别考虑一下:

  • 客户使用params中的signed_request发布到/tab
  • 应用程序解析signed_request并将结果存储在实例变量中。
  • 该应用重定向到/tab,即发送代码为302(或类似)的响应以及指向Location的{​​{1}}标头。这样就完成了请求/响应周期,实例变量将被丢弃。
  • 客户端发出新请求:GET到/tab。由于重定向工作的方式,这将不再具有与原始POST一起发送的参数。
  • 该应用尝试解析signed_request参数但崩溃,因为没有发送此类参数。

最简单的解决方案是仅渲染模板以响应POST而不是重定向。

如果您确实需要重定向,则需要仔细传递signed_request作为重定向路径中的查询参数。至少那是我过去使用的解决方案。可能有更简单的方法来解决这个问题,或者为您处理其中一些问题的库。