问题
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:
OpenSSL::SSL::SSLError SSL_connect returned=1 errno=0 state=SSLv3 read server certificate B: certificate verify failed
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.
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
回答1:
Ruby cannot find any root certificates. Here is an option for debugging purposes. Put following code at the begining of your script:
require 'openssl'
OpenSSL::SSL::VERIFY_PEER = OpenSSL::SSL::VERIFY_NONE
回答2:
Add the following code to 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:
/etc/pki/tls/certs/ca-bundle.crt
For Ubuntu its at:
/etc/ssl/certs/ca-certificates.crt
回答3:
I've been facing the same problem after updating Ruby running on Yosemite, but while trying to authenticate with Google.
Following this: https://toadle.me/2015/04/16/fixing-failing-ssl-verification-with-rvm.html
seemed to solve my problem.
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
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
回答4:
Looks like SSL verification is failing for Facebook. I'm no OpenSSL master, but I think this should work for you.
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:
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 file will work for you--just put it somewhere, give it necessary permissions, and point your app at it.
Thanks to Alex Kremer at this SO answer for the detailed instructions.
回答5:
This link should work. https://gist.github.com/fnichol/867550 Just follow the instructions. You will need to download Rails installer and run two command line functions.
回答6:
Do this, this will get ride of the certificate error with openssl
sudo curl http://curl.haxx.se/ca/cacert.pem -o /opt/local/etc/openssl/cert.pem
回答7:
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:
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.
来源:https://stackoverflow.com/questions/5711190/how-to-get-rid-of-opensslsslsslerror