OmniAuth & Facebook: проверка сертификата не выполнена
Я следил за Railscast # 235, чтобы попытаться установить минимальную аутентификацию Facebook.
Я сначала установил аутентификацию Twitter, как сделал сам Райан. Это работало безупречно.
Затем я перешел к добавлению входа в Facebook. Однако после авторизации приложения redirect на /auth/facebook/callback
неудачей:
- Как начать работу с TDD с помощью Ruby on Rails?
- curl: (1) Протокол https не поддерживается или отключен в libcurl
- Net :: SMTPAuthenticationError при отправке электронной почты из приложения Rails (в промежуточной среде)
- Добавить виртуальный атрибут для вывода json
- Миграции для Java
SSL_connect returned=1 errno=0 state=SSLv3 read server certificate B: certificate verify failed
Я работаю на localhost. Я не установил SSL в приложении. Что я делаю не так?
- ссылка для скачивания файла в рельсах
- Где хранить конфиденциальные данные в приложении public rails?
- Ruby on Rails - импорт данных из файла CSV
- Rails 3: Как «redirect_to» в вызове Ajax?
- Можно ли часто обновлять частичное использование Ajax?
- Серийный цикл ActiveRecord с использованием JSON вместо YAML
- Rails не правильно декодирует JSON из jQuery (массив становится хешем с целыми ключами)
- GroupingError: ERROR: столбец должен отображаться в предложении GROUP BY или использоваться в агрегатной функции
Реальная проблема заключается в том, что Faraday (который использует Omniauth / Oauth для своих HTTP-вызовов) не устанавливает параметр ca_path для OpenSSL. По крайней мере, на Ubuntu большинство корневых сертификатов хранятся в «/ etc / ssl / certs». Поскольку Faraday не устанавливал эту переменную (и в настоящее время не имеет способа сделать это) , OpenSSL не нашел корневой сертификат для SSL-сертификата Facebook.
Я отправил запрос на передачу в Faraday, который добавит поддержку этой переменной, и, надеюсь, они скоро придут к этим изменениям. До тех пор вы можете обезопасить faraday, чтобы выглядеть так или использовать мою вилку Faraday . После этого вы должны указать версию 0.3.0 из OAuth2 gem в Gemspec, которая поддерживает передачу опций 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
Итак, напомню:
-
Чтобы поддерживать SSL ca_path, необходимо обновить Faraday.Установите Faraday 0.6.1 -
Ваше приложение должно использовать OAuth2 версии 0.3.0.Возможно, вам понадобится fork omniauth, так как в настоящее время он имеет незначительную версию зависимости в дереве 0.2.x.Обновление до OmniAuth 0.2.2 - Измените инициализатор вашего провайдера, чтобы указать путь к сертификату вашей системы («/ 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.crt к указанному пути.
open-ssl version -a
Я на ubuntu 10.10 (Maverick) … боролся около 6 часов, прежде чем я получил его на работу, обмен опытом
- не пробовал патч обезьяны
- попробовал {: client_options => {: ssl => {: ca_path => “/ etc / ssl / certs}}}, но все еще не работал
- проверенный ruby 1.8.7 все еще не работал
- пробовал разные версии omniauth & faraday, до сих пор не повезло.
Единственное, что заставило его работать, было следующее (спасибо Алексу)
if Rails.env.development? OpenSSL::SSL::VERIFY_PEER = OpenSSL::SSL::VERIFY_NONE end
Удалось пройти проверку SSL-сертификата, как и должно быть. Мой проект использует идентификатор 37signals для интеграции 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
Где «CLIENT_ID», «CLIENT_SECRET» вы можете получить по адресу 37signals.com и пакет документации gd_bundle.crt от GoDaddy, потому что 37-значный код использует их CA.
Если вы развертываете в 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
Я решил это с помощью пакета 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
Изменить: проверьте ответ ниже, поскольку это более актуально
Это сработало для меня (исправить любезно 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
Я просто добавил этот параметр в development.rb
Я знаю, это звучит тривиально, но убедитесь, что вы используете правильный протокол. Я продолжал получать эту ошибку, а затем понял, что пытаюсь подключиться через http. 1,5 часа впустую, потому что я идиот.
Кажется, это проблема 1.9.x. Возврат к 1.8.7 исправил проблему.
Вот что я сделал, что помогло, если у вас возникли проблемы с Leopard.
Мой сертификат был старым и нуждался в обновлении. Я скачал это:
http://curl.haxx.se/ca/cacert.pem
Затем заменил мой сертификат, который был найден здесь на Leopard:
/usr/share/curl/curl-ca-bundle.crt
Перезагрузите все, что у вас есть, и получите доступ к нему!
Просто потому, что инструкции были немного разными для того, что сработало для меня, я думал, что добавляю свои 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 все, что мне нужно было сделать, это update /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
Вола!
Наконец я нашел исправление для Горного льва. См .: 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
И вы сделали.