32
votes

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

7
We can't tell you what code to change if you don't show us the code you already have. :) Perhaps this helps?Michelle Tilley
Sorry, this is a link to my code and details of the problem link @brandonTilleyEugene
are you getting a stack trace? There are a few libraries down the stack (OmniAuth, OAuth2, Faraday, etc.) and if you have a stack trace it would probably help a lot.Michelle Tilley
@brandonTilley, sorry, for going round and round. New to this forum, by the way, this is a link to my framework stack trace. linkEugene
No problems ^_^ Added an answer, finally :) Good luckMichelle Tilley

7 Answers

23
votes

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
9
votes

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
7
votes

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

6
votes

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.

1
votes

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.

0
votes

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
0
votes

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.