J'ai suivi Railscast # 235 pour essayer de configurer une authentification Facebook minimale.
J'ai d'abord configuré une authentification Twitter, comme l'a fait Ryan lui-même. Cela a parfaitement fonctionné.
Je suis ensuite passé à l'ajout d'une connexion Facebook. Cependant, après avoir autorisé l'application, la redirection vers /auth/facebook/callback
échoue avec:
SSL_connect returned=1 errno=0 state=SSLv3 read server certificate B: certificate verify failed
Je travaille sur localhost. Je n'ai configuré aucun SSL dans l'application. Qu'est-ce que je fais mal?
Le vrai problème est que Faraday (qu'Omniauth/Oauth utilise pour ses appels HTTP) n'est pas ne définissait pas la variable ca_path pour OpenSSL. Au moins sur Ubuntu, la plupart des certificats racine sont stockés dans "/ etc/ssl/certs". Depuis Faraday n'est pas ne définissait pas cette variable (et n'a actuellement pas de méthode pour le faire), OpenSSL n'est pas n'a pas trouvé le certificat racine du certificat SSL de Facebook.
J'ai soumis une demande d'extraction à Faraday qui ajoutera le support pour cette variable et j'espère qu'ils introduiront bientôt ce changement. Jusque-là, vous pouvez monkeypatch faraday pour ressembler à this ou utiliser ma fourchette de Faraday . Après cela, vous devez spécifier la version 0.3.0 de la gemme OAuth2 dans votre Gemspec qui prend en charge le passage des options SSL à Faraday. Il ne vous reste plus qu'à passer à Faraday 0.6.1, qui prend en charge le passage de la variable ca_path et à passer à OmniAuth 0.2.2, qui possède les dépendances appropriées pour OAuth2. Vous pourrez ensuite résoudre correctement ce problème en ajoutant simplement ce qui suit à votre initialiseur Omniauth:
Rails.application.config.middleware.use OmniAuth::Builder do
provider :facebook, FACEBOOK_KEY, FACEBOOK_SECRET, {:client_options => {:ssl => {:ca_path => "/etc/ssl/certs"}}}
end
Donc, pour récapituler:
Espérons que les prochaines versions de Faraday et d'Omniauth intégreront cette solution.
Merci à KirylP ci-dessus pour m'avoir mis sur la bonne voie.
J'avais ce problème et j'ai essayé d'utiliser l'argument: ca_path sans succès. Après avoir parcouru Github pendant un certain temps, je suis tombé sur une suggestion qui mentionnait l'utilisation de: ca_file et pointais directement vers la certification.
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 vous devez obtenir le chemin d'accès à vos fichiers de certification de systèmes (et à votre utilisation de Linux), tapez simplement à partir du terminal. Cela vous donnera un tas d'informations sur votre configuration SSL, y compris le chemin d'accès (reportez-vous à OPENSSLDIR). Vous devrez ajouter certs/ca-bundle.crt au chemin fourni.
open-ssl version -a
Je suis sur Ubuntu 10.10 (Maverick) ... j'ai lutté environ 6 heures avant de le faire fonctionner, partageant mon expérience
La seule chose qui l'a fait fonctionner était la suite (merci Alex)
if Rails.env.development?
OpenSSL::SSL::VERIFY_PEER = OpenSSL::SSL::VERIFY_NONE
end
Géré pour passer par la vérification du certificat SSL comme il se doit. Mon projet utilise 37 ID de signaux pour l'intégration 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
Où 'CLIENT_ID', 'CLIENT_SECRET' vous pouvez obtenir sur 7signals.com et le fichier de paquets de certificats Gd_bundle.crt de - GoDaddy car 37 signaux utilisent leur autorité de certification.
Si vous déployez sur Heroku, vous souhaitez pointer vers l'emplacement du fichier spécifique. Cela fonctionne pour moi (dans 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
J'ai résolu cela avec le bundle CA de: http://certifie.com/ca-bundle/
Et dans mon initialiseur Devise:
:client_options => { :ssl => { :ca_file => "#{Rails.root}/config/ca-bundle.crt" } } }
On dirait qu'Omniauth utilise désormais une version plus récente de Faraday, ce qui explique pourquoi le patch singe ci-dessus ne fonctionnait pas pour moi. Je suis d'accord qu'il doit y avoir un meilleur moyen, mais pour toute autre personne qui a juste besoin de le faire fonctionner pour tester, voici une version mise à jour:
(créez un fichier dans votre répertoire initialiseurs avec le code suivant)
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
toutes les solutions n'ont pas fonctionné pour moi, alors j'ai trouvé ça
http://railsapps.github.io/openssl-certificate-verify-failed.html
rvm osx-ssl-certs update all
osx 10.8 Ruby 2.0.0 via rvm
Modifier: vérifiez la réponse ci-dessous car elle est plus pertinente
Cela a fonctionné pour moi (correction avec l'aimable autorisation de https://github.com/jspooner ):
Créez un fichier dans le répertoire de votre initialiseur avec le patch singe suivant:
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
J'utilise Faraday 0.6.1 et OAUTH2 (seul, pas enveloppé par quoi que ce soit). Cela a suffi à résoudre le problème pour moi (sur Gentoo, devrait fonctionner sur Ubunto)
Tourne ça
client = OAuth2::Client.new(FACEBOOK_API_KEY, FACEBOOK_API_SECRET, :site => FACEBOOK_API_SITE)
Dans ce
client = OAuth2::Client.new(FACEBOOK_API_KEY, FACEBOOK_API_SECRET, :site => FACEBOOK_API_SITE, :ssl => {:ca_path => '/etc/ssl/certs' })
Je sais que cela semble trivial, mais assurez-vous que vous utilisez le bon protocole. J'ai continué à recevoir cette erreur, puis j'ai réalisé que j'essayais de me connecter via http. 1,5 heure perdue parce que je suis un idiot.
Mon problème a été résolu en s'assurant que openSSL utilisait le bon répertoire de certificats:
Pour mon système (ubuntu64), c'était: ENV ['SSL_CERT_DIR'] = '/ usr/share/ca-certificate /'
Cela utilisait jruby-openssl avec JRuby 1.6.0
Je viens d'ajouter ce paramètre à development.rb
Sur Ubuntu, tout ce que j'avais à faire était de mettre à jour /environments/development.rb pour:
Rails.application.config.middleware.use OmniAuth::Builder do
provider :facebook, FACEBOOK_KEY, FACEBOOK_SECRET, {:client_options => {:ssl => {:ca_path => "/etc/ssl/certs"}}}
end
et alors:
cd /etc/ssl/certs
Sudo wget http://curl.haxx.se/ca/cacert.pem
wola!
J'ai rencontré une erreur similaire en utilisant RVM sur Mountain Lion. Il semble que Ruby ne trouve pas le certificat CA dont il a besoin pour autoriser la connexion SSL. Vous devez en installer un. Cette solution a fait l'affaire:
http://fredwu.me/post/28834446907/fix-openssl-error-on-mountain-lion-and-rvm
(Bien que je ne puisse pas réellement charger cette page dans mon navigateur, je devais la trouver dans le cache Google.)
Voici la réponse courte:
curl http://curl.haxx.se/ca/cacert.pem -o ~/.rvm/usr/ssl/cert.pem
Et tu as fini.
Voici ce que j'ai fait pour vous aider si vous rencontrez spécifiquement un problème avec Leopard.
Mon certificat était ancien et devait être mis à jour. J'ai téléchargé ceci:
http://curl.haxx.se/ca/cacert.pem
Puis remplacé mon certificat qui a été trouvé ici sur Leopard:
/usr/share/curl/curl-ca-bundle.crt
Rechargez tout ce que vous avez qui y accède et vous devriez être prêt à partir!
J'ai finalement trouvé un correctif pour Mountain Lion. Voir: http://coderwall.com/p/f4hyqw
rvm pkg install openssl
rvm reinstall 1.9.3 --with-openssl-dir=$rvm_path/usr
Cela semble être un problème 1.9.x. Le retour au 1.8.7 a résolu le problème.
Juste parce que les instructions étaient légèrement différentes pour ce qui a fonctionné pour moi, j'ai pensé ajouter mes 2 cents:
Je suis sur OS X Lion et j'utilise macports et rvm
J'ai installé curl-ca-bundle:
Sudo port install curl-ca-bundle
Ensuite, j'ai ajusté ma configuration omniauth comme suit:
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