如何使 Heroku 上的 Sinatra 应用程序与 fb_graph 一起使用?

发布于 2024-12-28 17:56:22 字数 483 浏览 4 评论 0原文

我通过使用 Facebook 提供的功能(获取云应用程序或类似的东西)启动它,在 Heroku 上创建了一个基于 sinatra 的 Facebook 应用程序。一切工作正常,但当我尝试使用 Facebook 的分数时,我意识到 Heroku(即 Mogli)使用的 Facebook API 不支持分数。 所以我尝试重写代码以使用fb_graph。但由于这比我从一个空文件开始的所有事情都造成了更多的混乱。但我就是无法让它发挥作用。

所以基本上我想要一个基于 Sinatra 的 Heroku 应用程序的简单示例,该应用程序使用 fb_graph。示例应该只包含身份验证,因为其他一切看起来都非常简单并且有大量文档。仅初始身份验证是行不通的。

我想使用默认的 oauth2 方法进行回调,因为它对我来说更自然,但我对一切都持开放态度。我知道有一个 Rails 示例,但我就是无法理解它,而且由于我的应用程序非常简单,Rails 似乎有点强大。

如果有人能为我提供我想做的事情所需的几行代码,那就太好了!

I created a sinatra based facebook app on Heroku by initiating it with the feature provided by Facebook (Get Cloud App or something like that). Everything worked fine, but when I tried to use the Scores from Facebook, I realized that the Facebook API used by Heroku (which is Mogli) does not support Scores.
So I tried to rewrite the code to use fb_graph. But since that created more confusion than everything I started with an empty file. But I just can't make it work.

So basically I would like a simple example for a Sinatra based app on heroku which uses fb_graph. The samples should only contain authentication, since everything else seems pretty straight forward and has a lot of documentation. Just the initial authentication just doesn't work.

I would like to use the default oauth2 approach with the callback, since it just feels more natural to me, but I'm open for everything. I know there is a Rails example, but I just can't get my head around it and since my app will be very simple Rails seems a bit overpowered.

It would be great if anyone could give me just the few lines necessary for what I would like to do!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

怪我鬧 2025-01-04 17:56:22

我发现这有点混乱。旧的教程和代码不再有意义了。

您可以使用 Heroku + Facebook OmniAuth 示例 来创建外部网站(不是画布应用程序) )进行服务器端 Facebook(和许多其他)身份验证。

当您这样做时,OmniAuth 将为您提供您需要传递给 fb_graph 的令牌。在提供的示例中,您可以添加另一个网址:

get '/me' do
  me = FbGraph::User.me(session['fb_token']).fetch
  "Hello " + me.name
end

对于画布应用程序,我根据 这个要点

require 'base64'
require 'openssl'
require 'json'

# This is inspired by [rack-facebook-signed-request](https://github.com/gamesthatgive/rack-facebook-signed-request)
#
# Usage
#
#     use Rack::FBSignedRequest, :secret => 'SECRET'
#
class Rack::FBSignedRequest
  def initialize(app, options)
    @app = app
    @options = options
  end

  def call(env)
    @request = Rack::Request.new(env)
    if @request.POST['signed_request']
      if facebook_params = parse_signed_request(@request.params['signed_request'])
        @request.params['facebook_params'] = facebook_params
        env['rack.request.query_hash'] = @request.params
        env['REQUEST_METHOD'] = 'GET'
        puts 'Valid signed request. Changed REQUEST_METHOD to GET.'

        if facebook_params['user_id']
          env['fb_user_id'] = facebook_params['user_id']
          env['fb_access_token'] = facebook_params['oauth_token']
          puts 'Request has been authorized.'
        else
          puts 'Request is not authorized.'
        end

      else
        puts 'Not a valid signed request'
      end
    else
       puts 'Not a signed_request'
    end

    @app.call(env)
  end

  private

  # The following code from omniauth

  def parse_signed_request(value)
    signature, encoded_payload = value.split('.')

    decoded_hex_signature = base64_decode_url(signature)
    decoded_payload = JSON(base64_decode_url(encoded_payload))

    unless decoded_payload['algorithm'] == 'HMAC-SHA256'
      raise NotImplementedError, "unkown algorithm: #{decoded_payload['algorithm']}"
    end

    if valid_signature?(@options[:secret], decoded_hex_signature, encoded_payload)
      decoded_payload
    end
  end

  def valid_signature?(secret, signature, payload, algorithm = OpenSSL::Digest::SHA256.new)
    OpenSSL::HMAC.digest(algorithm, secret, payload) == signature
  end

  def base64_decode_url(value)
    value += '=' * (4 - value.size.modulo(4))
    Base64.decode64(value.tr('-_', '+/'))
  end
end

如果您的应用程序已获得授权,这将为您提供当前的 fb_user_id 和 fb_access_token。请记住,您必须使用 javascript 或 iFrame 中的链接来请求应用授权这个案例。

I've found this to be a bit of a mess. Old tutorials and code just don't make sense anymore.

You can use the Heroku + Facebook OmniAuth example to do an external website (not a canvas app) that does server-side Facebook (and many others) authentication.

When you do that, OmniAuth will provide you with the token you need you need to pass to fb_graph. In the provided example you could add another url:

get '/me' do
  me = FbGraph::User.me(session['fb_token']).fetch
  "Hello " + me.name
end

For canvas apps, I added the following code to 'rack-facebook-request.rb' to my repo based on this gist

require 'base64'
require 'openssl'
require 'json'

# This is inspired by [rack-facebook-signed-request](https://github.com/gamesthatgive/rack-facebook-signed-request)
#
# Usage
#
#     use Rack::FBSignedRequest, :secret => 'SECRET'
#
class Rack::FBSignedRequest
  def initialize(app, options)
    @app = app
    @options = options
  end

  def call(env)
    @request = Rack::Request.new(env)
    if @request.POST['signed_request']
      if facebook_params = parse_signed_request(@request.params['signed_request'])
        @request.params['facebook_params'] = facebook_params
        env['rack.request.query_hash'] = @request.params
        env['REQUEST_METHOD'] = 'GET'
        puts 'Valid signed request. Changed REQUEST_METHOD to GET.'

        if facebook_params['user_id']
          env['fb_user_id'] = facebook_params['user_id']
          env['fb_access_token'] = facebook_params['oauth_token']
          puts 'Request has been authorized.'
        else
          puts 'Request is not authorized.'
        end

      else
        puts 'Not a valid signed request'
      end
    else
       puts 'Not a signed_request'
    end

    @app.call(env)
  end

  private

  # The following code from omniauth

  def parse_signed_request(value)
    signature, encoded_payload = value.split('.')

    decoded_hex_signature = base64_decode_url(signature)
    decoded_payload = JSON(base64_decode_url(encoded_payload))

    unless decoded_payload['algorithm'] == 'HMAC-SHA256'
      raise NotImplementedError, "unkown algorithm: #{decoded_payload['algorithm']}"
    end

    if valid_signature?(@options[:secret], decoded_hex_signature, encoded_payload)
      decoded_payload
    end
  end

  def valid_signature?(secret, signature, payload, algorithm = OpenSSL::Digest::SHA256.new)
    OpenSSL::HMAC.digest(algorithm, secret, payload) == signature
  end

  def base64_decode_url(value)
    value += '=' * (4 - value.size.modulo(4))
    Base64.decode64(value.tr('-_', '+/'))
  end
end

This will give you the current fb_user_id and fb_access_token if your app is authorised. Remember that you have to use javascript or a link in the iFrame to request app authorisation in this case.

寻找一个思念的角度 2025-01-04 17:56:22

看看 Koala gem,我发现它非常容易使用。

Take a look at the Koala gem, I found it quite easy to use.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文