【问题标题】:Using Devise oauth2 branch for Facebook canvas为 Facebook 画布使用设计 oauth2 分支
【发布时间】:2011-05-20 09:10:09
【问题描述】:

我正在使用 Devise gem 的 oauth2 分支为 facebook 创建一个 iframe 画布应用程序。 Facebook 连接很容易工作,但我对 gem 的了解不够,它如何使用omniauth、warden 等 - 让身份验证与 facebook 画布一起工作。

有没有人举例说明如何做到这一点?

澄清:这是在 facebook 应用程序设置中启用“beta”oauth 选项并将画布 URL 设置为 /users/oauth/facebook/callback/

我也在试图弄清楚如何获得扩展权限。

【问题讨论】:

    标签: ruby-on-rails ruby-on-rails-3 devise


    【解决方案1】:

    我能够通过一个丑陋的 hack 来解决这个问题。如果对这些模块的内部工作有更多了解的人会提出正确的方法来做到这一点,那就太好了——有很多方法我只是不知道足以提供一个干净的实现。我猴子修补了 oauth 助手以从签名请求中提取 oauth 令牌。我还没有完成实施,所以也许我会遇到更多麻烦。这也可以利用签名请求中包含的 user_id(facebook uid),而不是调用图形 api。

    如果用户还没有按照此处记录的方式获得授权,我已对此进行了更新以包含重定向:

    http://developers.facebook.com/docs/authentication/

    “如果 JSON 对象不包含 user_id 参数,您应该按照正常的 OAuth 2.0 Web 应用程序流程将用户重定向到应用程序授权屏幕。”

    但是,这会显示一个带有指向该 URL 链接的 facebook 徽标,然后将用户弹出 iframe - 我认为不应该存在的某种 iframe 被 facebook 失败。

    module Devise
      module Oauth
        module InternalHelpers
          def callback_action
            access_token = nil
            if params[:signed_request]
              signed_data = FacebookSignedRequest.new(params[:signed_request]).valid?
              if signed_data['oauth_token']
                access_token = oauth_config.access_token_by_token(signed_data['oauth_token'])
              else
                return redirect_to oauth_config.authorize_url(:redirect_uri => oauth_redirect_uri)
              end
            elsif params[:code]
              access_token = oauth_config.access_token_by_code(params[:code], oauth_redirect_uri)
            else
              return redirect_to oauth_config.authorize_url(:redirect_uri => oauth_redirect_uri)
            end
    
            self.resource = resource_class.send(oauth_model_callback, access_token, signed_in_resource) if access_token
    
            if resource && resource.persisted? && resource.errors.empty?
              set_oauth_flash_message :notice, :success
              sign_in_and_redirect resource_name, resource, :event => :authentication
            else
              session[oauth_session_key] = access_token.token
              clean_up_passwords(resource)
              render_for_oauth
            end
          end
    
          def valid_oauth_callback?
            return !!params[:signed_request]
          end
        end
      end
    end
    
    ### For parsing the signed request
    
    require 'base64'
    require 'json'
    require 'openssl'
    
    # the code is copied from
    # http://forum.developers.facebook.net/viewtopic.php?pid=250261
    class FacebookSignedRequest
    
      attr_reader :signed_request
    
      def initialize(signed_request)
        @signed_request = signed_request
      end
    
      def base64_url_decode str
        encoded_str = str.gsub('-','+').gsub('_','/')
        encoded_str += '=' while !(encoded_str.size % 4).zero?
        Base64.decode64(encoded_str)
      end
    
      def valid?
        secret = "facebook-secret"
    
        #decode data
        encoded_sig, payload = signed_request.split('.')
        sig = base64_url_decode(encoded_sig).unpack("H*")[0]
        data = JSON.parse base64_url_decode(payload)
    
        if data['algorithm'].to_s.upcase != 'HMAC-SHA256'
        # Rails.logger.error 'Unknown algorithm. Expected HMAC-SHA256'
          return false
        end
    
        #check sig
        expected_sig = OpenSSL::HMAC.hexdigest('sha256', secret, payload)
        if expected_sig != sig
        # Rails.logger.error 'Bad Signed JSON signature!'
          return false
        end
    
        data
      end
    end
    

    【讨论】:

      【解决方案2】:

      现在可能为时已晚,但你需要补充

      skip_before_filter :verify_authenticity_token, :only => [:action_name]
      

      到控制器的顶部。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2012-10-13
        • 1970-01-01
        • 2016-08-27
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多