法拉第超时错误在omniauth(自定义策略)/doorkeeper中。

6
我目前正在跟随这个 railscast,但在我的特定情况下,在omniauth的回调中遇到了Faraday超时错误。
目前,我正在使用Rails应用程序作为API,并在同一应用程序上使用Backbone作为JavaScript前端。
我决定使用OAuth锁定API,并提供了一个自定义策略供Omniauth访问API作为客户端,以及使用Doorkeeper处理授权逻辑。
 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

我这样包含了自定义策略:

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

我目前在我的bundle中使用这些gem

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

这里是我进行身份验证并尝试检索正确访问令牌的地方(也是我卡住的地方)。
 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

这是从routes.rb文件中的路由信息。

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

该应用程序无法渲染connectAPI操作,完全卡在这一点上(由服务器日志给出)。
  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.

许多UID / 重要信息已从日志中省略。
最后出现了这个错误:
Faraday :: Error :: TimeoutError(Timeout :: Error):
我希望我已经彻底解释了这个问题。
我不知道为什么应用程序似乎会在omniauth启动的回调部分冻结。 我尝试更新bundler,因为其他一些stackoverflow问题指向我,但它没有起作用。
也许我对OAuth2的理解有点模糊。
如果有人能帮助我,我将非常感激。

如果你解决了这个问题,请告诉我。我和你一样,也遇到了同样的困境。 - Jon Phenow
1个回答

5

我不确定这是否适用于你,以下是我的情况:

问题

  • 一个应用程序需要我们内部OAuth服务器上的数据
  • OAuth服务器上几乎没有数据
  • 我们想将App1的身份验证部分转移到App2中,而不移动数据

解决方案

  • App1将App2用作身份验证服务器
  • App2使用App1的用户数据

此解决方案的问题

死锁 - App1正在等待来自App2的OAuth响应,但为了完成该响应,App2必须等待来自App1的响应。

最终观察

在Rails(使用WebBrick)的开发模式下,无法运行多线程,因此请求可能永远无法完成。

我的解决方案

我的解决方案是安装puma并添加到config/environments/development.rb中:

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

当你启动服务器时,可以使用THREADS=1 rails s Puma来测试OAuth相关内容。

或者

或者你的情况可能完全不同,实际上你并没有在服务之间进行通信。你的extra_info(例如Github的 /user)端点在OAuth服务器上是否正常工作?你的回调函数是否真的起作用了呢?

希望这可以帮到你!


这绝对是第一个解决方案,而且非常合理。我安装了Puma并且它的表现非常出色! - Vivek
需要考虑的一件事情是(我们在我们的情况下不得不这样做),这是即将出现的问题的迹象。如果你已经遇到了这个问题,那么现在可能是重新思考项目架构的时候了,这样你就不必担心这种情况再次发生。不过很高兴这解决了你的问题! - Jon Phenow

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接