ruby-on-railsfacebookdeviseomniauthomniauth-facebook

omniauth-facebook gem: request.env["omniauth.auth"] is nil


I'm using the omniauth-facebook gem with devise. It was working until recently. I also recently upgrated to Rails 5.0.1 from Rails 4, but I'm not sure that's the cause.

I currently have 0 users, and I'm logged into Facebook. But when I try to sign up for my app with Facebook on localhost, I get this error:

NoMethodError in RegistrationsController#facebook
undefined method `provider' for nil:NilClass

Here is my User model. I marked the line that the error highlights.

User.rb

  devise :database_authenticatable, :registerable,
         :recoverable, :rememberable, :validatable,
         :omniauthable, :omniauth_providers => [:facebook]


  def self.from_omniauth(auth)
    where(provider: auth.provider, uid: auth.uid).first_or_create do |user| #ERROR
      @data = auth.info
      user.name = @data.name
      # ...
    end
  end

RegistrationsController

  def facebook
    @user = User.from_omniauth(request.env["omniauth.auth"])
    if @user.persisted?
      sign_in_and_redirect @user, :event => :authentication
      set_flash_message(:notice, :success, :kind => "Facebook") if is_navigational_format?
    else
      session["devise.facebook_data"] = request.env["omniauth.auth"]
      redirect_to new_user_registration_url
    end
  end

Also, here's my link:

<%= link_to "fb", user_facebook_omniauth_callback_path(:facebook, thing: @thing.id, degree: @degree, :format => :js) %>

The HTML Output:

<a href=\"/auth/facebook/callback.js?thing=2\">fb<\/a>

And the path:

localhost:3000/auth/facebook/callback.js?thing=2

So the problem is that request.env["omniauth.auth"] is nil for some reason. I can't find any traces of similar errors in any documentation.

Anyone encounter this before or have any thoughts?


Solution

  • To authenticate via facebook all you need is to put a link from your Site to facebook like this:

    www.yoursite.com/auth/facebook
    

    and then set up a route to receive the callback from Facebook with the authentication hash:

    #routes.rb      
    get 'auth/facebook/callback'  => 'sessions#create_facebook'
    

    Can you specify how the output of this line looks like or why you are passing other information ?:

    <%= link_to "fb", user_facebook_omniauth_callback_path(:facebook, thing: @thing.id, degree: @degree, :format => :js) %>
    

    EDIT

    auth/facebook/callback is a get request. Facebook sends you the users authentication hash there. Only facebook itself should use that route. When you want to authenticate your link has to be:

    localhost:3000/auth/facebook
    

    They way you have it, omniauth is expecting facebook's authentication hash but receives "?thing=2" which results in a failed authentication. Omniauth tries to extract the information from "?thing=2" which is not a hash and when you try to access auth[provider], auth is empty and therefore provider is not defined either which results in :

    undefined method `provider' for nil:NilClass