6

我目前正在关注这个railscast,对于我的具体情况,我在omniauth 的回调中遇到了法拉第超时错误。

目前我使用 Rails 应用程序作为 API 和主干作为 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

我目前在我的捆绑包中使用这些宝石

# 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.

日志中省略了许多 uids/重要信息。

最后给出这个错误:

Faraday::Error::TimeoutError(超时::Error):

我希望我对这个问题的解释已经彻底。

我不知道为什么应用程序似乎在omniauth的回调启动部分冻结。我已经尝试更新捆绑器,因为其他一些 stackoverflow 问题已经指出了我,但它不起作用。

也许我对 OAuth2 的理解有点模糊。

如果有人可以帮助我,我将不胜感激

4

1 回答 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 服务器上运行?你的回调真的在做什么吗?

我希望这有帮助!

于 2012-08-24T16:12:24.253 回答