OmniAuth&Facebook:证书validation失败
我遵循Railscast#235来尝试设置最小的Facebook身份validation。
我首先设置了Twitterauthentication,就像Ryan自己做的一样。 这工作完美无瑕。
然后,我继续添加Facebooklogin。 但是,在授权应用程序后,redirect到/auth/facebook/callback
失败:
SSL_connect returned=1 errno=0 state=SSLv3 read server certificate B: certificate verify failed
我正在本地主机上工作。 我没有在应用程序内设置任何SSL。 我究竟做错了什么?
真正的问题是Faraday(Omniauth / Oauth用于HTTP调用) 不是没有设置OpenSSL的ca_pathvariables。 至less在Ubuntu上,大多数root证书都存储在“/ etc / ssl / certs”中。 由于法拉第不是没有设置这个variables(目前还没有这样做的方法) ,OpenSSL 不是没有findFacebook的SSL证书的根证书。
我已经向法拉第提交了一个pull请求,这个请求将会增加对这个variables的支持,希望他们很快能够引入这个变化。 在此之前,你可以用法拉第的叉子来兜售法拉第。 之后,您应该在您的Gemspec中指定版本0.3.0的OAuth2 gem,它支持将SSL选项传递到法拉第。 您现在需要做的只是升级到Faraday 0.6.1,它支持传递ca_pathvariables,并升级到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。安装法拉第0.6.1 -
您的应用需要使用OAuth2 0.3.0版本。您可能需要fork omniauth,因为它目前在0.2.x树中具有次要版本依赖性。升级到OmniAuth 0.2.2 - 修改您的提供程序初始化程序以指向您的系统的证书path(Ubuntu等的“/ etc / ssl / certs”)
希望法拉第和Omniauth的下一个版本都将包含这个解决scheme。
感谢上面的KirylP设置我在正确的道路上。
我有这个问题,并尝试使用:ca_path参数没有成功。 看了Github一段时间后,我碰到一个build议,提到使用:ca_file直接指向authentication。
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
如果您需要获取系统authentication文件(以及您使用的Linux)的path,只需从terminal键入。 这会给你一些关于你的SSL设置的信息,包括path(参考OPENSSLDIR)。 您需要将certs / ca-bundle.crt添加到提供的path中。
open-ssl version -a
我在Ubuntu 10.10(Maverick)…挣扎大约6个小时才开始工作,分享我的经验
- 没有尝试猴子补丁
- 尝试{:client_options => {:ssl => {:ca_path =>“/ etc / ssl / certs”}}但仍然没有工作
- 试过ruby1.8.7仍然没有工作
- 尝试不同版本的omniauth和法拉第,仍然没有运气。
唯一让它工作的是跟随(感谢亚历克斯)
if Rails.env.development? OpenSSL::SSL::VERIFY_PEER = OpenSSL::SSL::VERIFY_NONE end
pipe理像通过SSL证书validation一样。 我的项目使用37signals ID进行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
你可以在37signals.com获得'CLIENT_ID','CLIENT_SECRET',并且从GoDaddy获得证书包gd_bundle.crt ,因为37signals正在使用他们的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
我使用来自http://certifie.com/ca-bundle/的; CA包解决了这个问题
在我的devise初始值:
:client_options => { :ssl => { :ca_file => "#{Rails.root}/config/ca-bundle.crt" } } }
看起来Omniauth现在使用更新版本的法拉第,这解释了为什么上面的猴子补丁不适合我。 我同意一定有更好的办法,但是对于任何需要testing的人来说,这里是一个更新的版本:
(使用以下代码在初始化程序目录中创build一个文件)
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
所有的解决scheme都不适合我,然后我find了这个
http://railsapps.github.io/openssl-certificate-verify-failed.html
rvm osx-ssl-certs update all
osx 10.8ruby2.0.0通过rvm
编辑:检查下面的答案,因为它更相关
这工作对我来说(修复https://github.com/jspooner ):
使用以下猴子补丁在您的初始化程序目录中创build一个文件:
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
我正在使用法拉第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 1.6.0使用jruby-openssl
我只是将此设置添加到development.rb
我知道这听起来微不足道,但确保你使用正确的协议。 我不断得到这个错误,然后意识到,我试图通过HTTP连接。 因为我是个白痴,所以浪费了1.5个小时。
这似乎是一个1.9.x的问题。 恢复到1.8.7解决了这个问题。
如果您在Leopard上遇到问题,那么我所做的就是如此。
我的证书是旧的,需要更新。 我下载了这个:
http://curl.haxx.se/ca/cacert.pem
然后把我在豹上find的证书换成了豹:
/usr/share/curl/curl-ca-bundle.crt
重新加载任何你有访问它,你应该是好的去!
只是因为说明对我来说有点不一样,所以我想我加了2美分:
我在OS X Lion上使用macports和rvm
我安装了curl-ca-bundle:
sudo port install curl-ca-bundle
然后我调整了我的omniauthconfiguration是这样的:
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上,我所要做的就是更新/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
沃拉!
我终于find了一个山狮的修复。 请参阅: http : //coderwall.com/p/f4hyqw
rvm pkg install openssl rvm reinstall 1.9.3 --with-openssl-dir=$rvm_path/usr
我在山狮上使用RVM时遇到了类似的错误。 看来,Ruby无法find授权SSL连接所需的CA证书。 你需要安装一个。 这个解决scheme诀窍:
http://fredwu.me/post/28834446907/fix-openssl-error-on-mountain-lion-and-rvm
(虽然我实际上无法在浏览器中加载该页面,但我必须在Googlecaching中find它。)
以下是简短的回答:
curl http://curl.haxx.se/ca/cacert.pem -o ~/.rvm/usr/ssl/cert.pem
你完成了。
- Facebooklogin消息:“URL阻止:此redirect失败,因为redirectURI未在应用程序的”客户端OAuth设置“中列入白名单。
- Facebooklogin“给定的URL不允许应用程序configuration”
- ProGuard找不到引用的库
- Facebook:永久页面访问令牌?
- Java示例如何使用OAuth在GAE上使用Facebook帐户login
- 什么是获得持久令牌从服务器发布到Facebook粉丝页的步骤
- 在调用FB.init()之前调用FB.getLoginStatus()
- 调用线程必须是STA,因为许多UI组件都需要这个
- 我们如何使用新的Facebook标签实现跟踪主题标签