Как запускать команды cURL в Rails - PullRequest
0 голосов
/ 14 марта 2020

Я использую Ruby в Rails 5, и мне нужно выполнить следующую команду в моем приложении:

curl -F 'client_id=126581840734567' -F 'client_secret=678ebe1b3b8081231aab27dff738313' -F 'grant_type=authorization_code' -F 'redirect_uri=https://uri.com/' -F 'code=AQBi4L2Ohy3Q_N3V48OygFm0zb3gEsL985x5TIyDTNDJaLs93BwXiT1tyGYWoCg1HlBDU7ZRjUfLL5HVlzw4G-7YkVEjp6Id2WuqOz0Ylt-k2ADwDC5upH3CGVtHgf2udQhLlfDnQz5NPsnmxjg4bW3PJpW5FaQs8fn1ztgYp-ssfAf6IRt2-sI45ZC8cqqr5K_12y0Nq_Joh0H-tTfVyNLKatIxHPCqRDb3tfqgmxim1Q' https://api.instagram.com/oauth/access_token

, чтобы оно возвращало что-то вроде:

{"access_token": "IGQVJYS0k8V6ZACRC10WjYxQWtyMVRZAN8VXamh0RVBZAYi34RkFlOUxXZnTJsbjlEfnFJNmprQThmQ4hTckpFUmJEaXZAnQlNYa25aWURnX3hpO12NV1VMWDNMWmdIT3FicnJfZAVowM3VldlVWZAEViN1ZAidHlyU2VDMUNuMm2V", "user_id": 17231445640157812}

Есть ли способ заставить Rails выполнять эти типы команд? Я пробовал следующее:

uri = URI.parse('https://api.instagram.com/oauth/access_token')
http = Net::HTTP.new(uri.host, uri.port)
request = Net::HTTP::Post.new(uri.request_uri)
request.set_form_data({
  "client_id" => "126581840734567",
  "client_secret" => "678ebe1b3b8081231aab27dff738313",
  "grant_type" => "authorization_code",
  "redirect_uri" => "http://nace.network/",
  "code" => params[:code]
  })    


res = Net::HTTP.start(uri.hostname, uri.port) do |http|
  http.request(request)
end

, но я получаю следующую ошибку:

end of file reached

в этой строке:

res = Net::HTTP.start(uri.hostname, uri.port) do |http|
  http.request(request)
end

Ответы [ 2 ]

2 голосов
/ 14 марта 2020

Вы используете HTTPS, поэтому вам нужно добавить это в свой код:

Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |http|
  res = http.request(request)
end

Но если вам не нужны постоянные соединения, вы также можете использовать это:

res = Net::HTTP.post_form(uri, 
  "client_id" => "126581840734567",
  "client_secret" => "678ebe1b3b8081231aab27dff738313",
  "grant_type" => "authorization_code",
  "redirect_uri" => "http://nace.network/",
  "code" => params[:code]
)

Кроме того, вы можете рассмотреть возможность использования такой библиотеки, как Фарадей , с которой гораздо проще иметь дело.

0 голосов
/ 14 марта 2020

Редактировать

Это из комментария TinMan ниже, звуковые точки.

Использование cURL изнутри Ruby или Rails чрезвычайно ценно. Внутри cURL существует невероятное количество функциональности, которая не реализована в Rails или Ruby; Даже HTTP-клиентам Ruby трудно реплицировать его, поэтому cURL очень приемлем в зависимости от потребностей приложения. И, в зависимости от приложения, поскольку cURL находится в скомпилированном C, он может легко обойти чистых Ruby клиентов.

Curl - это средство выдачи HTTP (или HTTP) запросов от команды line.

Вы не хотите использовать CURL в Rails. Вы хотите выдавать HTTP-запросы из Rails. С помощью curl все в порядке, это один из способов выдавать HTTP-запросы с помощью Rails.

Мы можем уточнить это далее, если вы хотите выдавать HTTP-запросы с Ruby. Сужать / перебирать до самой базовой c версии проблемы всегда полезно.

Мы знали, что все это уже, вероятно, - все еще стоит записать для всех нас, чтобы извлечь выгоду!

Используйте HTTP в Ruby

Мы хотим использовать HTTP-клиент. Их много, но для этого я собираюсь использовать Фарадей (драгоценный камень), потому что мне это нравится.

Вы хорошо начали со встроенных Ruby в NET:HTTP но я предпочитаю DSL Фарадея. В результате получается более читаемый и расширяемый код.

Итак, вот класс! Я только что проверил это так, используйте в качестве отправной точки. Убедитесь, что вы написали несколько юнит-тестов для него.

    # This is a Plain Old Ruby Object (PORO)
# It will work in Rails but, isn't Rails specific.
require 'faraday' # This require is needed as it's a PORO.

class InstagramOAuth
  attr_reader :code

  # The code parameter will likely change frequently, so we provide it
  # at run time.
  def initialize(code)
    @code = code
  end

  def get_token
    connection.get('/oauth/access_token') do |request|
      request.params[:code] = code
    end
  end

  private

  def connection
    @connection ||= Faraday.new(
      url: instagram_api_url,
      params: params,
      ssl: { :ca_path => https_certificate_location }
    )
  end

  def instagram_api_url
    @url ||= 'https://api.instagram.com'
  end

  # You need to find out where these are for your self.
  def https_certificate_location
    '/usr/lib/ssl/certs'
  end

  def params
    # These params likely won't change to often so we set a write time
    # in the class like this.
    {
      client_id: '126581840734567',
      client_secret: '678ebe1b3b8081231aab27dff738313',
      grant_type: 'authorization_code',
      redirect_uri: 'https://uri.com/'
    }
  end
end

# How do we use it? Like so

# Your big old authorisation code from your question
code = 'AQBi4L2Ohy3Q_N3V48OygFm0zb3gEsL985x5TIyDTNDJaLs93BwXiT1tyGYWoCg1HlBDU'\
       '7ZRjUfLL5HVlzw4G-7YkVEjp6Id2WuqOz0Ylt-k2ADwDC5upH3CGVtHgf2udQhLlfDnQz'\
       '5NPsnmxjg4bW3PJpW5FaQs8fn1ztgYp-ssfAf6IRt2-sI45ZC8cqqr5K_12y0Nq_Joh0H'\
       '-tTfVyNLKatIxHPCqRDb3tfqgmxim1Q'

# This will return a Faraday::Response object but, what is in it?
response = InstagramOAuth.new(code).get_token

# Now we've got a Hash
response_hash = response.to_hash

puts 'Request made'
puts "Request full URL: #{response_hash[:url]}"
puts "HTTP status code: #{response_hash[:status]}"
puts "HTTP response body: #{response_hash[:body]}"

Когда я запустил фрагмент кода выше, я получил следующее. Класс работает, вам просто нужно настроить параметры запроса, пока вы не получите то, что вы хотите. Надеемся, что класс демонстрирует, как отправлять HTTP-запросы в Ruby / Rails.

Request made
Request full URL: https://api.instagram.com/oauth/access_token?client_id=126581840734567&client_secret=678ebe1b3b8081231aab27dff738313&code=AQBi4L2Ohy3Q_N3V48OygFm0zb3gEsL985x5TIyDTNDJaLs93BwXiT1tyGYWoCg1HlBDU7ZRjUfLL5HVlzw4G-7YkVEjp6Id2WuqOz0Ylt-k2ADwDC5upH3CGVtHgf2udQhLlfDnQz5NPsnmxjg4bW3PJpW5FaQs8fn1ztgYp-ssfAf6IRt2-sI45ZC8cqqr5K_12y0Nq_Joh0H-tTfVyNLKatIxHPCqRDb3tfqgmxim1Q&grant_type=authorization_code&redirect_uri=https%3A%2F%2Furi.com%2F
HTTP status code: 405
HTTP response body: 

Дополнительное чтение

. https://lostisland.github.io/faraday/usage/

. https://github.com/lostisland/faraday/wiki/Setting-up-SSL-certificates

...