6

I'm currently following along with this railscast and for my specific situation am running into a Faraday timeout error on the callback from omniauth.

Currently I'm using a rails application as an API and backbone as a javascript front-end (on the same application)

I decided I wanted to lock down the API with OAuth and provided a custom strategy for Omniauth to access the API as a client as well as Doorkeeper to handle the authorization logic

 module OmniAuth
      module Strategies
        class Twiddle < OmniAuth::Strategies::OAuth2
          option :name, :twiddle
    
          option :client_options, {
            site: "http://localhost:3001",
            authorize_path: "/oauth/authorize"
          }
    
          uid do
            raw_info["id"]
          end
    
          info do
            { 
              firstName: raw_info["firstName"],
              lastName: raw_info["lastName"], 
              email: raw_info["email"]
            }
          end
    
          def raw_info
            @raw_info ||= access_token.get('/api/v1/user').parsed
          end
        end
      end
    end

I included the custom strategy like this:

require File.expand_path('lib/omniauth/strategies/twiddle', Rails.root)

Rails.application.config.middleware.use OmniAuth::Builder do
  provider :twiddle, id, secret # Omitting the actual ones for obvious reasons
end

I am currently using these gems in my bundle

# OAuth 
gem 'oauth2'
gem 'omniauth'
gem 'omniauth-oauth2'
gem 'omniauth-facebook'
gem 'doorkeeper'

Here is where I authenticate and attempt to retrive the proper access token (and also where I get stuck)

 def loginParse
    if ( user = User.authenticate( params[:email], params[:password] ) ) 
      session[:user_id] = user.id
      redirect_to '/auth/twiddle/' 
    else 
      render :controller => "authentication", :action => "loginIndex", :notice => "Incorrect credentials" 
    end
  end

Here is the routing from the routes.rb

  # Oauth urls
  match '/auth/twiddle/callback', to: "authentication#connectAPI"
  match "/auth/facebook/callback", to: "authentication#loginSocialMedia"

The application never is able to render the connectAPI action, getting COMPLETELY stuck at this point (given by the server logs)

  User Load (0.4ms)  SELECT `users`.* FROM `users` WHERE `users`.`id` = 1 LIMIT 1
  Doorkeeper::Application Load (0.2ms)  SELECT `oauth_applications`.* FROM `oauth_applications` WHERE `oauth_applications`.`uid` = '' LIMIT 1
  CACHE (0.0ms)  SELECT `users`.* FROM `users` WHERE `users`.`id` = 1 LIMIT 1
  Doorkeeper::AccessToken Load (0.3ms)  SELECT `oauth_access_tokens`.* FROM `oauth_access_tokens` WHERE `oauth_access_tokens`.`revoked_at` IS NULL AND `oauth_access_tokens`.`application_id` = 1 AND `oauth_access_tokens`.`resource_owner_id` = 1 ORDER BY created_at desc LIMIT 1
   (0.1ms)  BEGIN
  Doorkeeper::AccessGrant Load (0.2ms)  SELECT `oauth_access_grants`.* FROM `oauth_access_grants` WHERE `oauth_access_grants`.`token` = '' LIMIT 1
  SQL (1.1ms)  INSERT INTO `oauth_access_grants` (`application_id`, `created_at`, `expires_in`, `redirect_uri`, `resource_owner_id`, `revoked_at`, `scopes`, `token`) VALUES (1, '2012-08-08 03:10:31', 600, 'http://localhost:3001/auth/twiddle/callback', 1, NULL, '', '')
   (1.4ms)  COMMIT
Redirected to http://localhost:3001/auth/twiddle/callback?code=a
Completed 302 Found in 12ms (ActiveRecord: 3.7ms)
(twiddle) Callback phase initiated.

Many of the uids/important information have been omitted from the log.

Finally this error is given:

Faraday::Error::TimeoutError (Timeout::Error):

I hope I have been thorough in my explanation of this problem.

I don't know why exactly the application seems to be freezing at the callback initiated part of omniauth. I have tried updating bundler as a few other stackoverflow questions have pointed me to but it is not working.

Perhaps my understanding of OAuth2 is a bit murky.

If anyone can help me, I would greatly appreciate it

Community
  • 1
  • 1
Vivek
  • 621
  • 7
  • 18

1 Answers1

5

I'm not sure this applies to you been here was my scenario:

Problem

  • An app with data that our internal OAuth server wants
  • An OAuth server with little, to no data on it
  • We want to offload the authentication portion of App1 to App2 without moving data

Solution

  • App1 uses App2 as the Authentication server
  • App2 uses App1 for user data

Problem from this solution

Deadlock - App1 is waiting for an OAuth response from App2, but to complete that response App2 must wait for a response from App1.

Final observation

In development mode on Rails (with WebBrick) you can't run multi-threaded, so the request may never be allowed to complete.

My solution

My solution was to install puma and add to config/environments/development.rb:

if ENV["THREADS"]
  config.threadsafe!
end

Then when you start the server you'd do THREADS=1 rails s Puma to test your OAuth stuff.

OR

Or your scenario is completely different and you're actually not communicating between your services. Is your extra_info (like Github's /user) endpoint functioning on the OAuth server? Is your callback actually doing anything?

I hope this helps!

Jon Phenow
  • 3,974
  • 5
  • 26
  • 30
  • Definitely it was the first solution and it makes perfect sense. I installed puma and it worked like a charm! – Vivek Sep 08 '12 at 21:15
  • One thing to consider though (we had to with our situation) is that this is sign of trouble to come. If you've already run into this it might be time to re-think the architecture of the project such that you don't have to worry about this occurring. Glad this resolved your issue, though! – Jon Phenow Sep 10 '12 at 20:12