Ruby OAuth Nightmare: использование контактов API - PullRequest
3 голосов
/ 11 октября 2010

Последние несколько дней я бился головой о стену, поддерживая возможность добавления контакта в API контактов Google в моем приложении на Rails 3.Несмотря на множество неудачных попыток, я, наконец, добился определенного прогресса, применив гем Ruby OAuth и следуя приведенному здесь учебнику: http://everburning.com/news/google-analytics-oauth-and-ruby-oh-my/

Когда я следую этому в консоли, я иду дальше, чем в своемПриложение Rails.Я могу создать токен доступа, пройти аутентификацию в службе Google с помощью определенной области действия API-интерфейса контактов и применить токен 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.[]

Но значения, которые там находятся - сессия [: request_token] и параметры [: oauth_verifier] - присутствуют и учитываются в этом действии!Я не могу понять, что здесь ноль.

Так что я думаю, мне нужно сначала выяснить эту вторую проблему, но бонусные баллы также и за решение первой проблемы.: -)

Спасибо за чтение.

Аарон.

Ответы [ 2 ]

0 голосов
/ 14 декабря 2010

Unknown authorization header обычно означает, что ваша подпись не соответствует отправленной вами. Я не рекомендую драгоценный камень oauth. Он полон ошибок и странных проблем и не может корректно экранировать определенные параметры.

Gem Signet является официально поддерживаемым гемом для доступа к API Google в Ruby.

Вот как вы могли бы реализовать это с помощью 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)
0 голосов
/ 11 октября 2010

Попробуйте установить / получить данные сеанса со строкой, а не символом, т.е. session["request_token"], а не session[:request_token]. Я знаю, что раньше у меня была такая проблема.

...