Ruby-on-rails 如何摆脱 OpenSSL::SSL::SSLError
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/5711190/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to get rid of OpenSSL::SSL::SSLError
提问by Eugene
I am trying to authenticate users with Facebook using OmniAuth. Initially, it was working, but along the way it just stopped working and started to give me this error message:
我正在尝试使用 OmniAuth 向 Facebook 验证用户。最初,它正在工作,但一路上它只是停止工作并开始给我这个错误消息:
OpenSSL::SSL::SSLError SSL_connect returned=1 errno=0 state=SSLv3 read server certificate B: certificate verify failed
OpenSSL::SSL::SSLError SSL_connect 返回=1 errno=0 state=SSLv3 读取服务器证书B:证书验证失败
The same code works well for Twitter and I can't seem to understand why it doesn't work for Facebook. I have looked online for help, but I haven't been successful.
相同的代码适用于 Twitter,我似乎无法理解为什么它不适用于 Facebook。我在网上寻求帮助,但我没有成功。
This is the link to the website I am building: http://www.bestizz.com/
And this url would give you the error message: http://www.bestizz.com/auth/facebook
这是我正在构建的网站的链接:http: //www.bestizz.com/
这个 url 会给你错误信息:http: //www.bestizz.com/auth/facebook
回答by RAJ
Ruby cannot find any root certificates. Here is an option for debuggingpurposes. Put following code at the begining of your script:
Ruby 找不到任何根证书。这是用于调试目的的选项。将以下代码放在脚本的开头:
require 'openssl'
OpenSSL::SSL::VERIFY_PEER = OpenSSL::SSL::VERIFY_NONE
回答by Amal Kumar S
Add the following code to config/initializers/fix_ssl.rb
将以下代码添加到 config/initializers/fix_ssl.rb
require 'open-uri'
require 'net/https'
module Net
class HTTP
alias_method :original_use_ssl=, :use_ssl=
def use_ssl=(flag)
self.ca_file = "/etc/pki/tls/certs/ca-bundle.crt" # for Centos/Redhat
self.verify_mode = OpenSSL::SSL::VERIFY_PEER
self.original_use_ssl = flag
end
end
end
Note:
笔记:
Many operating systems already come with a supplied certificate bundle. For example in Red Hat Enterprise Linux and CentOS it's installed in:
许多操作系统已经附带了提供的证书包。例如在 Red Hat Enterprise Linux 和 CentOS 中,它安装在:
/etc/pki/tls/certs/ca-bundle.crt
For Ubuntu its at:
对于 Ubuntu,它位于:
/etc/ssl/certs/ca-certificates.crt
回答by rpbaltazar
I've been facing the same problem after updating Ruby running on Yosemite, but while trying to authenticate with Google.
更新在优胜美地上运行的 Ruby 后,我一直面临同样的问题,但在尝试向 Google 进行身份验证时。
Following this: https://toadle.me/2015/04/16/fixing-failing-ssl-verification-with-rvm.htmlseemed to solve my problem.
按照这个:https://toadle.me/2015/04/16/fixing-failing-ssl-verification-with-rvm.html似乎解决了我的问题。
For the sake of history I'll quote:
为了历史,我将引用:
So the rvm-installed ruby does look into the wrong directory for certificates whereas the OSX-ruby will look into the correct one. In it's case that is a OSX system-directory.
So the rvm-installed ruby is the problem.
This discussion on Github finally gave the solution: Somehow RVM comes with a precompiled version of ruby that is statically linked against an openssl that looks into /etc/openssl for it's certificates.
What you wanna do is NOT TO USE any of the precompiled rubies and rather have ruby compiled on your local machine, like so: rvm install 2.2.0 --disable-binary
所以 rvm 安装的 ruby 确实会查看错误的证书目录,而 OSX-ruby 会查看正确的目录。在这种情况下,这是一个 OSX 系统目录。
所以 rvm 安装的 ruby 是问题所在。
Github 上的这个讨论最终给出了解决方案:不知何故,RVM 附带了一个预编译的 ruby 版本,该版本与 openssl 静态链接,该 openssl 查看 /etc/openssl 的证书。
您想要做的不是使用任何预编译的 ruby,而是在您的本地机器上编译 ruby,如下所示: rvm install 2.2.0 --disable-binary
In the end, I had to run:
最后,我不得不运行:
rvm uninstall ruby-2.2.4
rvm install ruby-2.2.4 --disable-binary
gem pristine --all
Hope this helps
希望这可以帮助
回答by Michelle Tilley
Looks like SSL verification is failing for Facebook. I'm no OpenSSL master, but I think this should work for you.
看起来 Facebook 的 SSL 验证失败。我不是 OpenSSL 大师,但我认为这对你有用。
Assuming you're using an up-to-date version of OmniAuth (>= 0.2.2, I assume you are) and a version of Faraday >= 0.6.1 (the stack trace says you are), you can pass the location of your CA certificates bundle. Modify your OmniAuth setup for Facebook accordingly:
假设您使用的是最新版本的 OmniAuth(>= 0.2.2,我假设您是)和 Faraday >= 0.6.1 的版本(堆栈跟踪表明您是),您可以传递位置您的 CA 证书捆绑包。相应地修改 Facebook 的 OmniAuth 设置:
Rails.application.config.middleware.use OmniAuth::Builder do
provider :facebook, 'appid', 'appsecret', {:scope => 'publish_stream,email', :client_options => {:ssl => {:ca_path => '/etc/ssl/certs'}}}
# other providers...
end
and replace '/etc/ssl/certs'with the path to your bundle. If you need one, I believe this filewill work for you--just put it somewhere, give it necessary permissions, and point your app at it.
并替换'/etc/ssl/certs'为您的包的路径。如果你需要一个,我相信这个文件对你有用——只要把它放在某个地方,给它必要的权限,然后让你的应用程序指向它。
Thanks to Alex Kremer at this SO answerfor the detailed instructions.
感谢 Alex Kremer 在这个 SO 答案中的详细说明。
回答by JohnOsborne
This link should work. https://gist.github.com/fnichol/867550Just follow the instructions. You will need to download Rails installer and run two command line functions.
这个链接应该有效。https://gist.github.com/fnichol/867550只需按照说明操作即可。您需要下载 Rails 安装程序并运行两个命令行功能。
回答by JBB
An ugly workaround I just did is to override the class in Net::HTTP and set the variable which tells it to not verify ssl certs:
我刚刚做的一个丑陋的解决方法是覆盖 Net::HTTP 中的类并设置告诉它不验证 ssl 证书的变量:
require 'net/http'
require 'openssl'
class Net::HTTP
alias_method :orig_connect, :connect
def connect
@ssl_context.verify_mode = OpenSSL::SSL::VERIFY_NONE
orig_connect
end
end
I did it this way because I don't want to muck with the source code of the gem which calls the gem which calls the gem which calls Net::HTTP. I should really go back and figure out how to nudge it to look at a separate cacert.pem file instead. I can't modify the server's cacert.pem file, or that would be the best route.
我这样做是因为我不想弄乱调用 gem 的 gem 的源代码,该 gem 调用调用 Net::HTTP 的 gem。我真的应该回去弄清楚如何推动它查看单独的 cacert.pem 文件。我无法修改服务器的 cacert.pem 文件,否则这将是最佳途径。
回答by Raymond Gao
Do this, this will get ride of the certificate error with openssl
这样做,这将通过 openssl 解决证书错误
sudo curl http://curl.haxx.se/ca/cacert.pem -o /opt/local/etc/openssl/cert.pem

