Кодирование GET с использованием OAuth в Ruby Twitter API - PullRequest
0 голосов
/ 07 декабря 2011

Я пытаюсь написать простое веб-приложение Ruby on Rails, которое регистрируется в Twitter через oAuth и получает список подписчиков пользователя, без использования существующей библиотеки oAuth .Используя их руководство по номеру https://dev.twitter.com/docs/auth/oauth,, мне удалось правильно выполнить вход в систему и, таким образом, получить последующие outh_token и oauth_token_secret.Однако, пытаясь закодировать GET-запрос для зарегистрированных подписчиков пользователя, я получаю 401 «Этот метод требует аутентификации».

Используя мой код и их пример данных, я вижу, что генерируюoauth_signature правильно.Возможно, я генерирую signature_base_string неправильно, но, видя, что он работает нормально при входе в систему, я не вижу, как это может быть неправильно во второй раз.Методы являются частью класса, поэтому ключ и секрет потребителя, очевидно, являются переменными класса.

Соответствующий код приведен ниже.Это вывод HTTP GET в «подписчиках», который дает 401. Я надеюсь, что это что-то смехотворно очевидное, что я просто упускаю возможность смотреть на это слишком долго!Я знаю, что у меня есть правильные значения, переданные функции в качестве параметров.Спасибо.

  def followees(auth_token, auth_token_secret, user_id)
    method = 'GET'
    base_uri = 'https://api.twitter.com/1/friends/ids.json'
    params = {
      'cursor' => '-1',
      'oauth_consumer_key' => @@consumer_key,
      'oauth_nonce' => generate_nonce, #not shown, no need!
      'oauth_signature_method' => 'HMAC-SHA1',
      'oauth_token' => auth_token,
      'oauth_timestamp' => Time.now.to_i.to_s,
      'oauth_version' => '1.0',
      'user_id' => user_id
    }
    signature_base_string = signature_base_string(method, base_uri, params)
    params['oauth_signature'] = url_encode(sign(@@consumer_secret + '&' + auth_token_secret, signature_base_string))
    header = header(params)
    base_uri += '?cursor=-1&user_id=' + user_id
    url = URI.parse(base_uri)
    http = Net::HTTP.new(url.host, 443)
    http.use_ssl = true
    resp, data = http.get(url.path, { 'Authorization' => header })
  end

  def signature_base_string(method, uri, params)
    encoded_params = params.sort.collect{ |k, v| url_encode("#{k}=#{v}") }.join("%26")
    method + '&' + url_encode(uri) + '&' + encoded_params
  end

  def url_encode(string)
    CGI::escape(string)
  end

  def sign(key, base_string)
    digest = OpenSSL::Digest::Digest.new('sha1')
    hmac = OpenSSL::HMAC.digest(digest, key, base_string)
    Base64.encode64(hmac).chomp.gsub(/\n/, '')
  end

  def header(params)
    header = "OAuth "
    params.each do |k, v|
      header += "#{k}=\"#{v}\", "
    end
    header.slice(0..-3)
  end

1 Ответ

1 голос
/ 07 декабря 2011

Разобрался. Нужен был перерыв, чтобы отступить от него! По сути, последняя строка в подписчиках не включала данные GET, поэтому

resp, data = http.get(url.path, { 'Authorization' => header })

должно было быть

resp, data = http.get(url.to_s, { 'Authorization' => header })

Я скопировал код для POSTing, поэтому там использовался только url.path.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...