2010-10-11 16 views
3

Я провел последние несколько дней, ударяя головой о стену, поддерживая возможность добавления контакта в API контактов Google в моем приложении Rails 3. Несмотря на множество ложных запусков, я, наконец, добился определенного прогресса, применив жемчужину Ruby OAuth и следуя инструкциям здесь:Ruby OAuth Nightmare: Использование контактов API

Когда я следую этому в консоли, я получаю больше, чем в моем приложении 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 = истина» заголовок берется, и как бы я от нее избавиться?

Но это еще хуже в приложении 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='[email protected]_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] - присутствуют и учитываются в этой акции! Я не могу понять, что здесь.

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

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

Aaron.

+0

Ба, я нашел проблему. Я использовал код от предыдущего разработчика, и он отменил переопределение метода Маршалла в environment.rb. Удалили это и все прояснилось. Часы впустую! –

+0

Просто примечание: «readbody = true» не является заголовком. Это фактически часть реализации объекта ответа Ruby. Это никогда не отправлялось по проводам ни одной из сторон и совершенно не связано с вопросом, который у вас был. –

ответ

0

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

+0

Извините, это не поможет. Значения сеанса четко видны в действии (вызов «logger.debug» REQUEST: «+ @request_token.проверять «дает правильные данные» и то же самое с параметром. Мое подозрение падает на вызов get_access_token, потому что я не могу найти что-то не так с этой строкой! Но я не знаю, как устранить неисправность кода в gem ... –

+0

И как насчет 'google_auth', имеет ли' session [: request_token] 'правильные данные? Если это так, разместите всю трассировку стека. –

0

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

Драгоценный камень 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) 

 Смежные вопросы

  • Нет связанных вопросов^_^