0

Google アカウントを介して単純な OpenID 認証を統合しようとしています。私は omniauth gem を使用しており、ローカル開発システム (Win7、ruby 1.8.7-p302、rails 2.3.8、omniauth 0.1.5) ではすべて正常に動作します。

この問題は、ホスティング (HostGator) にデプロイしたときの顔を示しています。アプリ (mongrel) はポート 12002 で開始し、HostGator の cPanel を介して、サブドメインの 1 つから書き換えられるように構成されています。

RewriteCond %{HTTP_HOST} ^subdomain.mycompany.com$ [OR]
RewriteCond %{HTTP_HOST} ^www.subdomain.mycompany.com$
RewriteRule ^(.*)$ "http\:\/\/127\.0\.0\.1\:12002\/$1" [P,L]

ブラウザが /auth/open_id になると、承認のために Google にリダイレクトされますが、return_to アドレスは subdomain.mycompany.com:12002 であり、Apache は 12002 をリッスンしないため、もちろん正しくありません。 ::OpenID と Rack::OpenID は、ポートなしでアドレスを組み立てますが、ユーザー アクセスの確認後、次の場合は最終段階になります。

Routing Error
No route matches "/403.shtml" with {:method=>:get}

問題は、私のサイトのアドレスが他の認証リクエストパラメーターでエンコードされていること(ある種のハッシュ)が回避することだと思います

4

3 に答える 3

1

ポートの問題は、RACK 要求がポートを計算する方法が原因です。ここにパッチがあります

require 'rack/utils'
module Rack
  class Request
    def port
      if host_with_port =~ /:(\d+)$/
        $1.to_i
      else
        standard_port
      end
    end

    # Returns the standard \port number for this request's protocol.
    def standard_port
      case protocol
        when 'https://' then 443
        else 80
      end
    end

    # Returns 'https://' if this is an SSL request and 'http://' otherwise.
    def protocol
      ssl? ? 'https://' : 'http://'
    end

    # Is this an SSL request?
    def ssl?
      @env['HTTPS'] == 'on' || @env['HTTP_X_FORWARDED_PROTO'] == 'https'
    end
  end
end

これは、rails ActionController::Request がポートを計算する方法です。

お役に立てれば

于 2010-12-02T04:29:36.883 に答える
0

Omniauthの最新バージョン(0.2.0.beta4)では、構成オプションとして指定full_hostして、各要求で評価されるように設定するか、固定値を使用することができます。

例(レール):

ActionController::Dispatcher.middleware.use OmniAuth::Builder do
    store = Rails.env.development? ? OpenID::Store::Filesystem.new("#{Rails.root}/tmp") : nil
    provider :open_id, store, :name => 'google', :identifier => 'https://www.google.com/accounts/o8/id', :scope => 'email'

    if Rails.env.production?
        configure do |config|
            config.full_host = lambda  do |env|
                req = Rack::Request.new(env)
                "#{req.scheme}://#{req.host}"  # req.host strips port number
            end
        end
    end
end
于 2011-02-14T20:44:41.817 に答える
0

良い...

403 エラーは、ホスティング セキュリティ ルールが非常に厳格であり、Google の OpenID 応答 (疑わしいほど長い) が拒否されたためです。ホスティング サポートにより解決されました。

return_to パラメーター内のポート番号の問題を解決するために ( freiwillenで対処)、次の (モンキー パス) 初期化子を作成しました。

module OmniAuth
  module Strategies
    # OmniAuth strategy for connecting via OpenID. This allows for connection
    # to a wide variety of sites, some of which are listed [on the OpenID website](http://openid.net/get-an-openid/).
    class OpenID
      protected
      def callback_url
        uri = URI.parse(request.url)
        uri.path += '/callback'

        # by KirylP: to overcome hosting subdomain forwarding to rails port        
        uri.port = '' if request.env.has_key? 'HTTP_X_FORWARDED_SERVER'

        uri.to_s
      end
    end
  end
end

module Rack
  class OpenID
    SERVER_PORT_TO_AVOID = 12002

    private
    def realm_url(req)
      url = req.scheme + "://"
      url << req.host

      scheme, port = req.scheme, req.port
      if scheme == "https" && port != 443 ||
          scheme == "http" && port != 80
        url << ":#{port}" if port != SERVER_PORT_TO_AVOID # KirylP
      end

      url
    end
  end
end

module OpenID
  class Consumer
    def complete(query, current_url)
      message = Message.from_post_args(query)

      current_url.sub!(":#{Rack::OpenID::SERVER_PORT_TO_AVOID}", '') # KirylP

      mode = message.get_arg(OPENID_NS, 'mode', 'invalid')
      begin
        meth = method('complete_' + mode)
      rescue NameError
        meth = method(:complete_invalid)
      end
      response = meth.call(message, current_url)
      cleanup_last_requested_endpoint
      if [SUCCESS, CANCEL].member?(response.status)
        cleanup_session
      end
      return response
    end    
  end
end

誰かがよりエレガントなソリューションを提案してくれることを願っています。

于 2010-11-06T14:21:55.450 に答える