Pregunta

He seguido Railscast # 235 para tratar de establecer un mínimo Facebook autenticación.

He estableció por primera vez una autenticación de Twitter, como se ha hecho por el propio Ryan. Eso funcionó sin problemas.

Luego se trasladó a la adición de un usuario de Facebook. Sin embargo, después de autorizar la aplicación de la redirección a /auth/facebook/callback falla con:

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

Estoy trabajando en el servidor local. Yo no se estableció ninguna SSL dentro de la aplicación. ¿Qué estoy haciendo mal?

¿Fue útil?

Solución

El problema real es que Faraday (que uso OmniAuth / Oauth por sus llamadas HTTP) no es no estaba estableciendo la variable de ca_path para OpenSSL. Al menos en Ubuntu, la mayoría de los CERT de la raíz se almacenan en "/ etc / ssl / certs". Desde Faraday no No fue el establecimiento de esta variable (y actualmente no tiene un método para hacerlo) , OpenSSL no es wasn 't encontrar el certificado raíz para el certificado SSL de Facebook.

He presentó una solicitud de extracción de Faraday que añadir soporte para esta variable y es de esperar que se tire en este cambio pronto. Hasta entonces, puede monkeypatch Faraday para parecerse este mi tenedor de Faraday . Después de eso, se debe especificar la versión 0.3.0 de la gema OAuth2 en su gemspec que soporta el paso de opciones SSL a través de Faraday. Todo lo que hay que hacer ahora es actualizar a 0.6.1 de Faraday, que pasa de soportes la variable ca_path y actualización a OmniAuth 0.2.2, que tiene las dependencias apropiadas para OAuth2. A continuación, ser capaz de solucionar este problema adecuadamente con sólo añadir lo siguiente a su OmniAuth inicializador:

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

Así que, para recapitular:

  1. Faraday necesita ser actualizado a ca_path soporte SSL. Instalar Faraday 0.6.1
  2. Su aplicación necesita utilizar OAuth2 versión 0.3.0. Es posible que tenga que desembolsar OmniAuth ya que actualmente tiene una dependencia menor en la versión 0.2.x árbol. Actualizar a OmniAuth 0.2.2
  3. Modificar su proveedor de inicializador a punto de ruta de certificación de su sistema ( "/ etc / ssl / certs" en Ubuntu y otros)

Esperemos que las próximas versiones de ambos Faraday y OmniAuth incorporará esta solución.

Gracias a KirylP anteriores para el establecimiento de mí en el camino correcto.

Otros consejos

Yo estaba teniendo este problema y trató con el: argumento ca_path sin éxito. Después de mirar a través de Github para un rato, me encontré con una sugerencia de que menciona el uso de:. Ca_file y punto directamente a la certificación

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

Si necesita obtener la ruta de los archivos de certificación de sistemas (y el uso de Linux) simplemente escriba desde el terminal. Esto le dará un montón de información acerca de la configuración de SSL, incluyendo la ruta (consulte OPENSSLDIR). Usted tendrá que añadir los CERT / ca-bundle.crt a la ruta proporcionada.

open-ssl version -a

Estoy en Ubuntu 10.10 (Maverick) ... luchado cerca de 6 horas antes de llegar al trabajo, compartiendo mi experiencia

  1. no probar el parche mono
  2. intentado {client_options: => {: ssl => {: Ca_path => "/ etc / ssl / certs"}} pero todavía no trabajado
  3. rubí tratado 1.8.7 todavía no trabajado
  4. probado versiones diferentes de OmniAuth y Faraday, sigue sin suerte.

La única cosa que hizo al trabajo seguía (gracias Alex)

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

Gestionado que pasar por la verificación de certificados SSL como tiene que ser. Mi proyecto es el uso de 37signals ID para la integración Basecamp (Rubí 1.9.2-p130, rieles 3.0.4).

RAILS_ROOT / config / inicializadores / 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

¿Dónde CLIENT_ID ', 'client_secret' se puede obtener en 37signals.com y certificados de archivo de paquete gd_bundle.crt GoDaddy porque 37signals están utilizando su CA.

Si va a distribuir a Heroku, que desea punto a la ubicación del archivo específico. Esto funciona para mí (en config / inicializadores / 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

He resuelto esto con CA paquete de: http://certifie.com/ca-bundle/

Y en mi Diseñar inicializador:

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

Las apariencias como OmniAuth ahora usa una versión más reciente de Faraday, lo que explica por qué el parche mono anterior no estaba trabajando para mí. Estoy de acuerdo en que debe haber una mejor manera, pero para cualquier otra persona que sólo tiene que conseguir que funcione a prueba, aquí está una versión actualizada:

(crear un archivo en el directorio de inicializadores con el siguiente código)

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

Todas las soluciones no funcionó para mí, entonces me he encontrado este

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

rvm osx-ssl-certs update all

osx 10.8 rubí 2.0.0 a través de RVM

Editar: Comprobar la respuesta a continuación, ya que es más relevante

Esto funcionó para mí (fix cortesía de https://github.com/jspooner ):

Crear un archivo en el directorio de su inicializador con el siguiente parche mono:

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

Estoy usando Faraday 0.6.1, y OAuth2 (solo, no envuelto por nada). Esto fue suficiente para resolver el problema para mí (en Gentoo, debería funcionar en Ubunto)

Convertir esto

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

En este

  client = OAuth2::Client.new(FACEBOOK_API_KEY, FACEBOOK_API_SECRET, :site => FACEBOOK_API_SITE, :ssl => {:ca_path => '/etc/ssl/certs' })

Mi problema fue resuelto por asegurar que openSSL estaba usando el directorio certificado derecha:

Para mi sistema (ubuntu64) fue: ENV [ 'SSL_CERT_DIR'] = '/ usr / share / ca-certificados /'

Esto fue usando jruby-openssl con JRuby 1.6.0

Acabo de añadir esta opción para development.rb

I know this sounds trivial, but make sure you are using the right protocol. I kept getting this error and then realized that I was trying to connect via http. 1.5 hours wasted because I am an idiot.

This seems to be a 1.9.x issue. Reverting to 1.8.7 fixed the issue.

Here's what I did that helped if you are specifically having a problem on Leopard.

My cert was old and needed to be updated. I downloaded this:

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

Then replaced my cert which was found here on Leopard:

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

Reload whatever you have that's accessing it and you should be good to go!

Just because instructions were a slight bit different for what worked for me, I thought I add my 2 cents:

I'm on OS X Lion and using macports and rvm

I installed curl-ca-bundle:

sudo port install curl-ca-bundle

Then I adjusted my omniauth config to be this:

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

On Ubuntu, all I had to do was update /environments/development.rb to:

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

and then:

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

wola!

I finally found a fix for Mountain Lion. See: http://coderwall.com/p/f4hyqw

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

I encountered a similar error using RVM on Mountain Lion. It seems that Ruby can't find the CA certificate it needs to authorise the SSL connection. You need to install one. This solution did the trick:

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

(Although I couldn't actually load that page in my browser, I had to find it in the Google cache.)

Here's the short answer:

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

And you're done.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top