代码之家  ›  专栏  ›  技术社区  ›  shmichael

OmniAuth&Facebook:证书验证失败[重复]

  •  65
  • shmichael  · 技术社区  · 14 年前

    我已经跟踪了 Railscast #235 尝试设置最小的Facebook身份验证。

    我首先建立了一个Twitter认证,就像Ryan自己做的那样。那是完美的。

    然后我继续添加一个Facebook登录。但是,在授权应用程序后,重定向到 /auth/facebook/callback 失败原因:

    SSL_connect returned=1 errno=0 state=SSLv3 read server certificate B: certificate verify failed
    

    我在本地主机上工作。我没有在应用程序中设置任何SSL。我做错什么了?

    18 回复  |  直到 14 年前
        1
  •  74
  •   Alex Kremer    13 年前

    真正的问题是Faraday(Omniauth/Oauth使用它进行HTTP调用) 不是 不是 (目前还没有这样做的方法) ,打开SSL 不是 找不到Facebook SSL证书的根证书。

    submitted a pull request to Faraday 这将增加对这个变量的支持,希望他们能很快加入这个变化。在那之前,你可以让法拉第看起来像 this my fork of Faraday . 之后,您应该在Gemspec中指定OAuth2 gem的0.3.0版本,它支持将SSL选项传递给Faraday。 现在您只需要升级到Faraday 0.6.1,它支持传递ca_path变量,并升级到OmniAuth 0.2.2,后者对OAuth2具有适当的依赖关系。然后,只需将以下内容添加到Omniauth初始值设定项中,就可以正确解决此问题:

    Rails.application.config.middleware.use OmniAuth::Builder do
        provider :facebook, FACEBOOK_KEY, FACEBOOK_SECRET, {:client_options => {:ssl => {:ca_path => "/etc/ssl/certs"}}}
    end
    

    1. 法拉第需要更新以支持SSL ca_路径。 安装 Faraday 0.6.1
    2. 你的应用需要使用OAuth2版本0.3.0。您可能需要分叉omniauth,因为它当前在0.2.x树中有一个次要的版本依赖项。 升级至OmniAuth 0.2.2
    3. 修改提供者初始值设定项以指向系统的证书路径(Ubuntu et al上的/etc/ssl/certs)

    希望法拉第和Omniauth的下一个版本都能包含这个解决方案。

        2
  •  18
  •   Emerson    13 年前

    我遇到了这个问题,尝试使用:ca_path参数,但没有成功。在查看Github一段时间后,我发现了一个建议,其中提到使用:ca_文件并直接指向证书。

    Rails.application.config.middleware.use OmniAuth::Builder do
      provider :facebook, 'secret_key', 'secret_key',
       :client_options => {:ssl => {:ca_file => '/etc/pki/tls/certs/ca-bundle.crt'}}}
    end
    

    open-ssl version -a
    
        3
  •  13
  •   EdChum Yuriy    12 年前

    我在Ubuntu10.10(特立独行)。。。在我开始工作前挣扎了6个小时,分享我的经验

    1. 没有试过猴子贴片
    2. {:ca_path=>“/etc/ssl/certs”}但仍然无法工作
    3. 尝试过的Ruby1.8.7仍然不起作用

    唯一能成功的就是跟踪(谢谢亚历克斯)

    if Rails.env.development? 
      OpenSSL::SSL::VERIFY_PEER = OpenSSL::SSL::VERIFY_NONE 
    end
    
        4
  •  7
  •   KirylP    14 年前

    成功地完成了SSL证书验证。

    RAILS_ROOT/config/initializers/omniauth.rb :

    require 'omniauth/oauth'
    
    Rails.application.config.middleware.use OmniAuth::Strategies::ThirtySevenSignals,
        'CLIENT_ID', 'CLIENT_SECRET', {client_options: {ssl: {ca_file: Rails.root.join('gd_bundle.crt').to_s}}}
    
    module OAuth2
      class Client
        def initialize(client_id, client_secret, opts = {})
          adapter = opts.delete(:adapter)
          self.id = client_id
          self.secret = client_secret
          self.site = opts.delete(:site) if opts[:site]
          self.options = opts
          self.connection = Faraday::Connection.new(site, {ssl: opts.delete(:ssl)})
          self.json = opts.delete(:parse_json)        # ^ my code starts here
    
          if adapter && adapter != :test
            connection.build { |b| b.adapter(adapter) }
          end
        end
      end
    end
    

    37signals.com 和证书捆绑文件 gd_束.crt GoDaddy 因为37个信号正在使用他们的CA。

        5
  •  6
  •   Anand Iyer    13 年前

    Rails.application.config.middleware.use OmniAuth::Builder do
      # This cert location is only for Heroku
      provider :facebook, APP_ID, APP_SECRET, {:client_options => {:ssl => {:ca_file => "/usr/lib/ssl/certs/ca-certificates.crt"}}}
    end
    
        6
  •  5
  •   Palo Delinčák    13 年前

    我用CA bundle解决了这个问题: http://certifie.com/ca-bundle/

    在我的设计初始化器中:

    :client_options => { :ssl => { :ca_file => "#{Rails.root}/config/ca-bundle.crt" } } }
    
        7
  •  4
  •   Zac Randles    13 年前

    (使用以下代码在初始化程序目录中创建文件)

    require 'faraday'
    module Faraday
    class Adapter
     class NetHttp < Faraday::Adapter
      def call(env)
      super
      url = env[:url]
      req = env[:request]
    
      http = net_http_class(env).new(url.host, url.inferred_port)
    
      if http.use_ssl = (url.scheme == 'https' && env[:ssl])
        ssl = env[:ssl]
        http.verify_mode = OpenSSL::SSL::VERIFY_NONE
        http.cert        = ssl[:client_cert] if ssl[:client_cert]
        http.key         = ssl[:client_key]  if ssl[:client_key]
        http.ca_file     = ssl[:ca_file]     if ssl[:ca_file]
        http.cert_store  = ssl[:cert_store]  if ssl[:cert_store]
      end
    
      http.read_timeout = http.open_timeout = req[:timeout] if req[:timeout]
      http.open_timeout = req[:open_timeout]                if req[:open_timeout]
    
      if :get != env[:method]
        http_request = Net::HTTPGenericRequest.new \
          env[:method].to_s.upcase,    # request method
          !!env[:body],                # is there data
          true,                        # does net/http love you, true or false?
          url.request_uri,             # request uri path
          env[:request_headers]        # request headers
    
        if env[:body].respond_to?(:read)
          http_request.body_stream = env[:body]
          env[:body] = nil
        end
      end
    
      begin
        http_response = if :get == env[:method]
          # prefer `get` to `request` because the former handles gzip (ruby 1.9)
          http.get url.request_uri, env[:request_headers]
        else
          http.request http_request, env[:body]
        end
      rescue Errno::ECONNREFUSED
        raise Error::ConnectionFailed, $!
      end
    
      http_response.each_header do |key, value|
        response_headers(env)[key] = value
      end
      env.update :status => http_response.code.to_i, :body => http_response.body
    
      @app.call env
    end
    end
    end
    end
    
        8
  •  4
  •   antpaw    11 年前

    所有的解决方案对我都不起作用,然后我找到了这个

    http://railsapps.github.io/openssl-certificate-verify-failed.html

    rvm osx-ssl-certs update all
    

    通过rvm的osx 10.8 ruby 2.0.0

        9
  •  2
  •   Jack Kinsella    13 年前

    编辑:检查下面的答案,因为它更相关

    https://github.com/jspooner ):

    使用以下monkey补丁在初始化程序的目录中创建一个文件:

    require 'faraday'
    module Faraday
    class Adapter
     class NetHttp < Faraday::Adapter
      def call(env)
        super
    
        is_ssl = env[:url].scheme == 'https'
    
        http = net_http_class(env).new(env[:url].host, env[:url].port || (is_ssl ? 443 : 80))
        if http.use_ssl = is_ssl
          ssl = env[:ssl]
          if ssl[:verify] == false
            http.verify_mode = OpenSSL::SSL::VERIFY_NONE
          else
            http.verify_mode = OpenSSL::SSL::VERIFY_NONE # <= PATCH or HACK ssl[:verify]
          end
          http.cert    = ssl[:client_cert] if ssl[:client_cert]
          http.key     = ssl[:client_key]  if ssl[:client_key]
          http.ca_file = ssl[:ca_file]     if ssl[:ca_file]
        end
        req = env[:request]
        http.read_timeout = net.open_timeout = req[:timeout] if req[:timeout]
        http.open_timeout = req[:open_timeout]               if req[:open_timeout]
    
        full_path = full_path_for(env[:url].path, env[:url].query, env[:url].fragment)
        http_req  = Net::HTTPGenericRequest.new(
          env[:method].to_s.upcase,    # request method
          (env[:body] ? true : false), # is there data
          true,                        # does net/http love you, true or false?
          full_path,                   # request uri path
        env[:request_headers])       # request headers
    
        if env[:body].respond_to?(:read)
          http_req.body_stream = env[:body]
          env[:body] = nil
        end
    
        http_resp = http.request http_req, env[:body]
    
        resp_headers = {}
        http_resp.each_header do |key, value|
          resp_headers[key] = value
        end
    
        env.update \
          :status           => http_resp.code.to_i,
          :response_headers => resp_headers,
          :body             => http_resp.body
    
        @app.call env
      rescue Errno::ECONNREFUSED
        raise Error::ConnectionFailed.new(Errno::ECONNREFUSED)
      end
    
      def net_http_class(env)
        if proxy = env[:request][:proxy]
          Net::HTTP::Proxy(proxy[:uri].host, proxy[:uri].port, proxy[:user], proxy[:password])
        else
          Net::HTTP
        end
      end
     end
    end
    end
    
        10
  •  2
  •   Warren Wilkinson    13 年前

    我使用的是法拉第0.6.1和OAUTH2(单独使用,不被任何东西包装)。这足以解决我的问题(在Gentoo上,应该在Ubanto上工作)

    把这个转过来

      client = OAuth2::Client.new(FACEBOOK_API_KEY, FACEBOOK_API_SECRET, :site => FACEBOOK_API_SITE)
    

      client = OAuth2::Client.new(FACEBOOK_API_KEY, FACEBOOK_API_SECRET, :site => FACEBOOK_API_SITE, :ssl => {:ca_path => '/etc/ssl/certs' })
    
        11
  •  1
  •   Daniel Honig    13 年前

    通过确保openSSL使用正确的证书目录解决了我的问题:

    ENV['SSL_CERT_DIR']='/usr/share/ca证书/'

    我刚把这个设置添加到development.rb

        12
  •  1
  •   jhamm    12 年前

    我知道这听起来很琐碎,但要确保使用正确的协议。我一直收到这个错误,然后意识到我试图通过http连接。因为我是个白痴浪费了1.5个小时。

        13
  •  0
  •   shmichael    14 年前

        14
  •  0
  •   Musicalmindz    13 年前

    如果你对豹子有什么特别的问题,我做了这些。

    我的证书旧了,需要更新。我下载了这个:

    http://curl.haxx.se/ca/cacert.pem

    /usr/share/curl/curl-ca-bundle.crt格式

        15
  •  0
  •   Hortitude    12 年前

    只是因为对我有用的东西的说明有点不同,我想我加上2美分:

    我在OS X Lion上使用macports和rvm

    我安装了curl ca bundle:

    sudo port install curl-ca-bundle
    

    Rails.application.config.middleware.use OmniAuth::Builder do
      provider :google_oauth2, APP_CONFIG['CONSUMER_KEY'], APP_CONFIG['CONSUMER_SECRET'],
               :scope => 'https://www.google.com/m8/feeds https://www.googleapis.com/auth/userinfo.profile',
               :ssl => {:ca_path => "/share/curl/curl-ca-bundle.crt"}
    end
    
        16
  •  0
  •   jesal    12 年前

    在Ubuntu上,我所要做的就是将/environments/development.rb更新为:

    Rails.application.config.middleware.use OmniAuth::Builder do
        provider :facebook, FACEBOOK_KEY, FACEBOOK_SECRET, {:client_options => {:ssl => {:ca_path => "/etc/ssl/certs"}}}
    end
    

    cd /etc/ssl/certs
    sudo wget http://curl.haxx.se/ca/cacert.pem
    

    哇哦!

        17
  •  0
  •   CrazyCoderMonkey    12 年前

    我终于找到了一个山狮的修复方法。见: http://coderwall.com/p/f4hyqw

    rvm pkg install openssl
    rvm reinstall 1.9.3 --with-openssl-dir=$rvm_path/usr
    
        18
  •  0
  •   Lachlan Cotter    12 年前

    我在山狮上使用RVM时遇到了类似的错误。Ruby似乎找不到授权SSL连接所需的CA证书。你需要安装一个。这个解决方案成功了:

    http://fredwu.me/post/28834446907/fix-openssl-error-on-mountain-lion-and-rvm

    (虽然我无法在浏览器中加载该页面,但我必须在Google缓存中找到它。)

    简而言之:

    curl http://curl.haxx.se/ca/cacert.pem -o ~/.rvm/usr/ssl/cert.pem