OmniAuth & Facebook: ошибка проверки сертификата [дубликат]


этот вопрос уже есть ответ здесь:

  • SSL_connect возвращается=1 для errno=0 состояние=протокол SSLv3 читать сертификат сервера Б: сертификат проверить не удалось 37 ответов

я следовал Railscast #235 чтобы попытаться настроить минимальную аутентификацию Facebook.

Я сначала настроил аутентификацию Twitter, как это сделано Сам Райан. Это сработало безупречно.

затем я перешел к добавлению логина Facebook. Однако после авторизации приложения перенаправление на /auth/facebook/callback выдает:

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

Я работаю на localhost. Я не настраивал SSL в приложении. Что я делаю не так?

18 64

18 ответов:

реальная проблема заключается в том, что Фарадей (который Omniauth / Oauth используют для своих HTTP-вызовов)не не устанавливал переменную ca_path для OpenSSL. По крайней мере, на Ubuntu большинство корневых сертификатов хранятся в "/etc/ssl/certs". С Фарадея не не устанавливал эту переменную (и в настоящее время не имеет метода для этого), OpenSSL не не удалось найти корневой сертификат для SSL-сертификата Facebook.

Я отправил запрос на вытягивание Фарадею который добавит поддержку для этой переменной и, надеюсь, они будут тянуть в этом изменении в ближайшее время. До тех пор, вы можете monkeypatch Фарадей выглядеть этой или использовать моя вилка Фарадея. После этого вы должны указать версию 0.3.0 драгоценного камня OAuth2 в своем Gemspec, который поддерживает передачу параметров 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

Итак, резюмируем:

  1. Фарадей должен быть обновлен для поддержки SSL ca_path. установить Фарадей 0.6.1
  2. ваше приложение должно использовать OAuth2 версии 0.3.0. Возможно, вам придется раскошелиться omniauth, так как это в настоящее время имеет незначительную зависимость от версии 0.2.x дерево. обновление до OmniAuth 0.2.2
  3. измените инициализатор поставщика, чтобы указать путь к сертификату вашей системы ("/etc/ssl/certs " на Ubuntu et al)

надеюсь, что в следующих выпусках Faraday и Omniauth будет включено это решение.

спасибо KirylP выше для установки меня на правильном пути.

у меня была эта проблема, и я попытался использовать аргумент :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

Если вам нужно получить путь к файлам сертификации ваших систем (и с помощью linux) просто введите с терминала. Это даст вам кучу информации о вашей настройке SSL, включая путь (см. OPENSSLDIR). Вам нужно будет добавьте certs / ca-bundle.ЭЛТ к пути при условии.

open-ssl version -a

Я на ubuntu 10.10 (Maverick)... боролись около 6 часов, прежде чем я получил его на работу, делюсь своим опытом

  1. не пробовал monkey patch
  2. пробовал {: client_options = > {: ssl => {: ca_path = > "/etc / ssl / certs"}} но все равно не работал
  3. пробовал ruby 1.8.7 еще не работал
  4. пробовал разные версии omniauth & faraday, все равно не повезло.

единственное, что заставило его работать, было следующее (Спасибо Алекс)

if Rails.env.development? 
  OpenSSL::SSL::VERIFY_PEER = OpenSSL::SSL::VERIFY_NONE 
end

удалось пройти проверку сертификата SSL, как это должно быть. Мой проект использует 37signals ID для интеграции Basecamp (Ruby 1.9.2-p130, Rails 3.0.4).

RAILS_ROOT/config/initializers / omniauth.РБ:

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

где 'CLIENT_ID', 'CLIENT_SECRET' вы можете получить на 37signals.com и certificates bundle file gd_bundle.ЭЛТ С GoDaddy потому что 37signals используют их CA.

при развертывании в Heroku необходимо указать конкретное расположение файла. Это работает для меня (в config / initializers / omniauth.РБ):

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

Я решил это с помощью пакета CA из: http://certifie.com/ca-bundle/

и в моем инициализаторе Devise:

:client_options => { :ssl => { :ca_file => "#{Rails.root}/config/ca-bundle.crt" } } }

похоже, Omniauth теперь использует более новую версию Faraday, что объясняет, почему патч обезьяны выше не работал для меня. Я согласен, что должен быть лучший способ, но для тех, кто просто должен заставить его работать, чтобы проверить, вот обновленная версия:

(создайте файл в каталоге инициализаторов со следующим кодом)

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

все решения не работают для меня, то я нашел это

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

rvm osx-ssl-certs update all

osx 10.8 ruby 2.0.0 через rvm

Edit: Проверьте ответ ниже, поскольку он более релевантен

это сработало для меня (исправить любезно https://github.com/jspooner):

создайте файл в каталоге инициализатора со следующим патчем обезьяны:

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

Я использую Faraday 0.6.1 и OAUTH2 (один, не завернутый ничем). Этого было достаточно, чтобы решить проблему для меня (на Gentoo, должен работать на Ubunto)

превратить этот

  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' })

моя проблема была решена, убедившись, что openSSL использует правильный каталог сертификатов:

для моей системы(ubuntu64) это было: ENV ['SSL_CERT_DIR'] = '/usr/share / ca-certificates/'

Это было использование jruby-openssl с JRuby 1.6.0

Я только что добавил этот параметр в разработку.РБ

Я знаю, это звучит тривиально, но убедитесь, что вы используете правильный протокол. Я продолжал получать эту ошибку, а потом понял, что я пытался подключиться через HTTP. 1,5 часа впустую, потому что я идиот.

Это, кажется, 1.9.х вопрос. Возвращаясь к 1.8.7 Исправлена проблема.

вот что я сделал, что помогло, если у вас конкретно возникли проблемы на леопарда.

мой сертификат был старым и нуждался в обновлении. Я скачал это:

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

затем заменил мой сертификат, который был найден здесь на Leopard:

/ usr / share/curl / curl-ca-bundle.ЭЛТ

перезагрузить что у вас есть доступ к нему, и вы должны быть хорошо идти!

просто потому, что инструкции были немного другими для того, что работало для меня, я думал, что добавлю свои 2 цента:

Я на OS X Lion и с помощью macports и rvm

Я установил curl-ca-bundle:

sudo port install curl-ca-bundle

затем я настроил свою конфигурацию omniauth следующим образом:

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

на Ubuntu все, что мне нужно было сделать, это обновить /среды/разработки.РБ:

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

воля!

Я, наконец, нашел исправление для Mountain Lion. Смотрите: http://coderwall.com/p/f4hyqw

rvm pkg install openssl
rvm reinstall 1.9.3 --with-openssl-dir=$rvm_path/usr

я столкнулся с подобной ошибкой, используя RVM на Mountain Lion. Похоже, что Ruby не может найти сертификат CA, необходимый для авторизации SSL-соединения. Вам нужно установить один. Это решение сделало трюк:

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

и вы сделали.