OmniAuth和Facebook:证书验证失败

shm*_*ael 65 facebook ruby-on-rails railscasts omniauth

我已经按照Railscast#235尝试建立一个最小的Facebook身份验证.

我首先建立了一个Twitter身份验证,就像Ryan本人所做的那样.这完美无瑕.

然后我继续添加Facebook登录.但是,在授权应用程序后,重定向/auth/facebook/callback失败并显示:

SSL_connect returned=1 errno=0 state=SSLv3 read server certificate B: certificate verify failed
Run Code Online (Sandbox Code Playgroud)

我正在使用localhost.我没有在应用程序中设置任何SSL.我究竟做错了什么?

Ale*_*mer 74

真正的问题是Faraday(Omniauth/Oauth用于他们的HTTP调用)不是没有为OpenSSL设置ca_path变量.至少在Ubuntu上,大多数根证书都存储在"/ etc/ssl/certs"中.由于法拉第是不是没有设置这个变量(和目前没有这样做的方法),OpenSSL的被发现不为Facebook的SSL证书的根证书.

我已经向法拉第提交了拉取请求,这将增加对此变量的支持,并希望他们很快就能实现这一变化.在那之前,你可以将monkeypatch法拉第看起来像这样或使用我的法拉第分叉.之后,您应该在Gemspec中指定版本0.3.0的OAuth2 gem,它支持将SSL选项传递到法拉第.您现在需要做的就是升级到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
Run Code Online (Sandbox Code Playgroud)

所以,回顾一下:

  1. 需要更新法拉第以支持SSL ca_path.安装法拉第0.6.1
  2. 您的应用需要使用OAuth2版本0.3.0.您可能需要fork omniauth,因为它当前在0.2.x树中具有次要版本依赖性.升级到OmniAuth 0.2.2
  3. 修改提供程序初始化程序以指向系统的证书路径(Ubuntu等人的"/ etc/ssl/certs")

希望法拉第和Omniauth的下一版本都将采用这种解决方案.

感谢上面的KirylP让我走上了正确的道路.

  • @mindtonic最简单的可能是下载并安装它们 - 如果你在Mac上,如果你已经安装了OpenSSL,你可能已经拥有它们了.否则,如果它真的只是用于开发,你可以添加一个初始化程序来关闭同行验证:`如果Rails.env.development?OpenSSL :: SSL :: VERIFY_PEER = OpenSSL :: SSL :: VERIFY_NONE end` (7认同)
  • 也适用于heroku! (6认同)
  • 顺便说一下,有谁知道你究竟如何在Windows中指定"cacerts.pem"路径?尝试了这两个:"C:\\ cacerts.pem"和"C:/cacerts.pem"(是的,文件*是*那里)没有运气.仍然是SSL错误.任何人? (5认同)
  • +1 @ Alex Kremer我用过:`Rails.application.config.middleware.use OmniAuth :: Builder do:facebook,FACEBOOK_KEY,FACEBOOK_SECRET,{:client_options => {:ssl => {:ca_path =>"/ etc/ssl/certs"}},:scope =>'publish_stream,email'} end`它可以工作,谢谢! (4认同)

小智 18

我遇到了这个问题并尝试使用:ca_path参数但没有成功.通过Github查看了一段时间后,我遇到了一个建议,提到使用:ca_file并直接指向认证.

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
Run Code Online (Sandbox Code Playgroud)

如果您需要获取系统认证文件(以及使用Linux)的路径,只需从终端输入即可.这将为您提供有关SSL设置的大量信息,包括路径(请参阅OPENSSLDIR).您需要将certs/ca-bundle.crt添加到提供的路径中.

open-ssl version -a
Run Code Online (Sandbox Code Playgroud)


小智 13

我在ubuntu 10.10(Maverick)上...在我开始工作前大约6个小时挣扎,分享我的经验

  1. 没试过猴子补丁
  2. 尝试{:client_options => {:ssl => {:ca_path =>"/ etc/ssl/certs"}}但仍然没有工作
  3. 试过ruby 1.8.7仍然没有用
  4. 尝试了不同版本的omniauth&faraday,仍然没有运气.

让它发挥作用的唯一因素是(感谢Alex)

if Rails.env.development? 
  OpenSSL::SSL::VERIFY_PEER = OpenSSL::SSL::VERIFY_NONE 
end
Run Code Online (Sandbox Code Playgroud)


Kir*_*ylP 7

管理必须通过SSL证书验证.我的项目使用37signals ID进行Basecamp集成(Ruby 1.9.2-p130,Rails 3.0.4).

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
Run Code Online (Sandbox Code Playgroud)

您可以从37signals.com获取'CLIENT_ID','CLIENT_SECRET',并从GoDaddy获取证书捆绑文件gd_bundle.crt,因为37signals正在使用他们的CA.


Ana*_*yer 6

如果要部署到Heroku,则需要指向特定的文件位置.这适用于我(在config/initializers/omniauth.rb中):

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
Run Code Online (Sandbox Code Playgroud)


Pal*_*čák 5

我通过CA捆绑解决了这个问题:http://certifie.com/ca-bundle/

在我的Devise初始化程序中:

:client_options => { :ssl => { :ca_file => "#{Rails.root}/config/ca-bundle.crt" } } }
Run Code Online (Sandbox Code Playgroud)