【问题标题】:Ruby OAuth Nightmare: Using Contacts APIRuby OAuth 噩梦:使用联系人 API
【发布时间】:2011-04-23 15:05:26
【问题描述】:

在过去的几天里,我一直在努力支持在我的 Rails 3 应用程序中向 Google Contacts API 添加联系人的能力。尽管有许多错误的开始,但我终于通过使用 Ruby OAuth gem 并按照此处的教程取得了一些进展:http://everburning.com/news/google-analytics-oauth-and-ruby-oh-my/

当我在控制台中执行此操作时,我比在我的 Rails 应用程序中更进一步。我可以创建访问令牌,使用联系人 API 的特定范围对 Google 服务进行身份验证,并应用 oauth_verifier 令牌来获取访问令牌。但是当需要推送数据时,我得到了这个错误:

response = at.post("https://www.google.com/m8/feeds/contacts/default/full", gdata)
 => #<Net::HTTPUnauthorized 401 Unknown authorization header readbody=true> 

“readbody=true”标头从何而来,我该如何摆脱它?

但在 Rails 应用程序中情况更糟。我有一个控制器操作(“googlecontacts”)创建请求令牌并将用户引导到使用 Google 的身份验证站点:

def googlecontacts

@card = Card.find_by_short_link(params[:id])

@consumer = OAuth::Consumer.new( 
  'anonymous', 
  'anonymous', 
  { 
    :site => 'https://www.google.com', 
    :request_token_path => '/accounts/OAuthGetRequestToken', 
    :access_token_path => '/accounts/OAuthGetAccessToken', 
    :authorize_path => '/accounts/OAuthAuthorizeToken', 
    :signature_method => 'HMAC-SHA1',
    :oauth_version => '1.0'
  })

@request_token = @consumer.get_request_token(
  {:oauth_callback => 'http://monkey.dev/cards/google_auth?redir='+@card.short_link}, 
  {:scope => "https://www.google.com/m8/feeds/"}
)

session[:request_token] = @request_token

redirect_to @request_token.authorize_url

end

这似乎有效;我得到一个工作请求令牌对象,用户被转发到 Google 服务进行身份验证。回调 URL(“google_auth”)应采用 oauth_verifier 令牌来创建访问令牌。这是控制器的开头:

def google_auth

   @access_token = session[:request_token].get_access_token(:oauth_verifier=>params[:oauth_verifier])

这就是它失败的地方。最后一行的错误是:

You have a nil object when you didn't expect it!
You might have expected an instance of Array.
The error occurred while evaluating nil.[]

但是其中的值—— session[:request_token] 和 params[:oauth_verifier]—— 存在并在该操作中说明!我无法弄清楚这里的 nil 是什么。

所以我想我需要先弄清楚第二个问题,但回答第一个问题也可以加分。 :-)

感谢阅读。

亚伦。

【问题讨论】:

  • 呸,我发现了问题。我使用的是以前开发人员的代码,他在 environment.rb 中隐藏了 Marshal 方法的重新定义。删除它,一切都清除了。浪费时间!
  • 请注意:“readbody=true”不是标题。它实际上是响应对象的 Ruby 实现的一部分。这不是任何一方通过网络发送的,与您遇到的问题完全无关。

标签: ruby-on-rails ruby oauth oauth-ruby


【解决方案1】:

尝试使用字符串而不是符号设置/获取会话数据,即session["request_token"],而不是session[:request_token]。我知道我以前也遇到过这个问题。

【讨论】:

  • 对不起,这没有帮助。在操作中可以清楚地看到会话值(对“logger.debug”REQUEST:“+@request_token.inspect”的调用会产生正确的数据),并且与 params 值相同。我的怀疑落在了对 get_access_token 的调用上,因为我找不到该线路的任何问题!但是不知道gem里面的代码怎么排错...
  • 那么在google_auth 中,session[:request_token] 那里也有正确的数据吗?如果是这样,请发布整个堆栈跟踪。
【解决方案2】:

Unknown authorization header 通常表示您的签名与您发送的内容不符。我不推荐oauth gem。它充满了错误和奇怪的问题,并且不能正确地转义某些参数。

Signet gem 是官方支持的用于在 Ruby 中访问 Google API 的 gem。

以下是您使用 Signet 实现此功能的方法:

require 'signet/oauth_1/client'
require 'addressable/uri'
card = Card.find_by_short_link(params[:id])
callback = Addressable::URI.parse('http://monkey.dev/cards/google_auth')
callback.query_values = {'redir' => card.short_link}

client = Signet::OAuth1::Client.new(
  :temporary_credential_uri =>
    'https://www.google.com/accounts/OAuthGetRequestToken',
  :authorization_uri =>
    'https://www.google.com/accounts/OAuthAuthorizeToken',
  :token_credential_uri =>
    'https://www.google.com/accounts/OAuthGetAccessToken',
  :client_credential_key => 'anonymous',
  :client_credential_secret => 'anonymous',
  :callback => callback
)

session[:temporary_credential] = (
  client.fetch_temporary_credential!(:additional_parameters => {
    :scope => 'https://www.google.com/m8/feeds/'
  })
)
redirect_to(client.authorization_uri)

【讨论】:

    猜你喜欢
    • 2010-12-22
    • 2017-03-21
    • 2010-12-21
    • 1970-01-01
    • 2012-11-24
    • 2022-06-29
    • 1970-01-01
    • 1970-01-01
    • 2020-03-14
    相关资源
    最近更新 更多