ruby-on-rails facebook railscasts omniauth

ruby on rails - OmniAuth y Facebook: verificación de certificado fallida



ruby-on-rails railscasts (18)

El hecho de que las instrucciones fueran un poco diferentes para lo que funcionó para mí, pensé que agregué mis 2 centavos:

Estoy en OS X Lion y uso macports y rvm

Instalé curl-ca-bundle:

sudo port install curl-ca-bundle

Luego ajusté mi configuración de omniauth para que sea esto:

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

Seguí Railscast # 235 para intentar configurar una mínima autenticación de Facebook.

Primero configuré una autenticación de Twitter, como lo hizo Ryan mismo. Eso funcionó a la perfección.

Luego pasé a agregar un inicio de sesión de Facebook. Sin embargo, después de autorizar la aplicación, 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 localhost. No configuré ningún SSL dentro de la aplicación. ¿Qué estoy haciendo mal?


El verdadero problema es que Faraday (que Omniauth / Oauth usa para sus llamadas HTTP) no estaba configurando la variable ca_path para OpenSSL. Al menos en Ubuntu, la mayoría de los certificadores de raíz se almacenan en "/ etc / ssl / certs". Como Faraday no está configurando esta variable (y actualmente no tiene un método para hacerlo) , OpenSSL no estaba buscando el certificado raíz para el certificado SSL de Facebook.

He enviado una solicitud de extracción a Faraday que agregará soporte para esta variable y es de esperar que aprovechen este cambio pronto. Hasta entonces, puedes hacer un parche en el tablero de Faraday para que se vea así o usar mi tenedor de Faraday . Después de eso, debe especificar la versión 0.3.0 de la gema OAuth2 en su Gemspec que admite el paso de las opciones SSL a Faraday. Todo lo que necesita hacer ahora es actualizar a Faraday 0.6.1, que admite el paso de la variable ca_path y actualizar a OmniAuth 0.2.2, que tiene las dependencias adecuadas para OAuth2. Entonces podrá corregir este problema de manera adecuada agregando lo siguiente a su inicializador Omniauth:

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

Entonces, para recapitular:

  1. Faraday debe actualizarse para admitir SSL ca_path. Instalar Faraday 0.6.1
  2. Tu aplicación necesita usar OAuth2 versión 0.3.0. Es posible que tenga que bifurcar omniauth ya que actualmente tiene una dependencia de versión menor en el árbol 0.2.x. Actualizar a OmniAuth 0.2.2
  3. Modifique su inicializador de proveedor para que apunte a la ruta del certificado de su sistema ("/ etc / ssl / certs" en Ubuntu et al)

Esperemos que los próximos lanzamientos de Faraday y Omniauth incorporen esta solución.

Gracias a KirylP más arriba por ponerme en el camino correcto.


En Ubuntu, todo lo que tuve que hacer fue actualizar /environments/development.rb a:

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

y entonces:

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

Wola!


Encontré un error similar al usar RVM en Mountain Lion. Parece que Ruby no puede encontrar el certificado de CA que necesita para autorizar la conexión SSL. Necesitas instalar uno. Esta solución hizo el truco:

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

(Aunque no podía cargar esa página en mi navegador, tenía que encontrarla en la memoria caché de Google).

Aquí está la respuesta corta:

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

Y tu estas listo.


Estaba teniendo este problema y traté de usar el argumento: ca_path sin éxito. Después de mirar a través de Github por un tiempo, encontré una sugerencia que mencionaba usar: ca_file y apuntaba 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 a los archivos de certificación de su sistema (y su uso de linux) simplemente escriba desde la terminal. Esto le dará un montón de información sobre su configuración de SSL, incluida la ruta (consulte OPENSSLDIR). Deberá agregar certs / ca-bundle.crt a la ruta proporcionada.

open-ssl version -a


Esto es lo que hice que ayudó si tienes un problema específico con Leopard.

Mi certificado era viejo y necesitaba ser actualizado. Descargué esto:

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

Luego reemplacé mi certificado que se encontró aquí en Leopard:

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

Recarga lo que tengas que esté accediendo a él y ¡deberías estar listo!


Esto parece ser un problema 1.9.x. Revertir a 1.8.7 solucionó el problema.


Estoy en Ubuntu 10.10 (Maverick) ... luché unas 6 horas antes de que funcionara, compartiendo mi experiencia

  1. no intenté el parche de mono
  2. intenté {: client_options => {: ssl => {: ca_path => "/ etc / ssl / certs"}} pero aún no funcionó
  3. intentado ruby ​​1.8.7 todavía no funcionó
  4. intenté diferentes versiones de omniauth y faraday, todavía no tuve suerte.

Lo único que lo hizo funcionar fue seguir (gracias Alex)

if Rails.env.development? OpenSSL::SSL::VERIFY_PEER = OpenSSL::SSL::VERIFY_NONE 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)

Dentro de esto

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


Finalmente encontré una solución para Mountain Lion. Ver: http://coderwall.com/p/f4hyqw

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


Lo resolví con CA bundle desde: http://certifie.com/ca-bundle/

Y en mi inicializador de Devise:

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


Logré pasar por la verificación de certificado SSL como debe ser. Mi proyecto usa 37signals ID para la integración de 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

Donde ''CLIENT_ID'', ''CLIENT_SECRET'' puede obtener 37signals.com y los certificados agrupan el archivo gd_bundle.crt de GoDaddy porque 37signals están usando su CA.


Mi problema se resolvió asegurándome de que openSSL usaba el directorio correcto de certificados:

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

Esto estaba usando jruby-openssl con JRuby 1.6.0

Acabo de agregar esta configuración a development.rb


Parece que Omniauth ahora usa una versión más nueva de Faraday, lo que explica por qué el parche de mono anterior no funcionaba para mí. Estoy de acuerdo en que debe haber una manera mejor, pero para cualquier otra persona que solo necesite que funcione para probar, aquí hay una versión actualizada:

(crea un archivo en tu 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


Sé que esto suena trivial, pero asegúrate de estar usando el protocolo correcto. Seguí recibiendo este error y luego me di cuenta de que estaba tratando de conectarme a través de http. 1.5 horas perdidas porque soy un idiota.


Si se está implementando en Heroku, quiere señalar la ubicación del archivo específico. Esto funciona para mí (en 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



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

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

Crea un archivo en el directorio de tu inicializador con el siguiente parche de 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