Недопустимая ошибка входа в запрос аутентификации okex api v3 - PullRequest
0 голосов
/ 31 января 2019

Я пытаюсь отправить аутентифицированный запрос на новый okex api.часть их документации :

Создание запроса

Все запросы REST должны содержать следующие заголовки:

OK-ACCESS-KEY Ключ API какстрока.

OK-ACCESS-SIGN Подпись в кодировке base64 (см. Подписание сообщения).

OK-ACCESS-TIMESTAMP Метка времени для вашего запроса.

OK-ACCESS-PASSPHRASE Фраза-пароль, указанная вами при создании ключа API.

Все тела запроса должны иметь тип содержимого application / json и быть действительным JSON.

Подписание сообщения

Заголовок OK-ACCESS-SIGN создается путем создания HMAC sha256 с использованием секретного ключа, декодированного по base64, в метке времени строки prehash + метод + requestPath + body (где + представляет конкатенацию строк), secretKey и base64-кодируют выходные данные.Например: sign = CryptoJS.enc.Base64.stringify (CryptoJS.HmacSHA256 (временная метка + 'GET' + '/ users / self / verify', secretKey))

Значение временной метки совпадает со значением OKЗаголовок -ACCESS-TIMESTAMP и точность в нанометрах.

Метод должен иметь значение UPPER CASE, например GET / POST.

requestPath - это путь запроса конечной точки, например, : / orders? Before =2 & limit = 30.

Тело является строкой тела запроса или опускается, если тела запроса нет (обычно для запросов GET).Например: {"product_id": "BTC-USD-0309", "order_id": "377454671037440"}

secretKey генерируется, когда пользователь подписывается на Apikey.Строка предварительного хэша: 2018-03-08T10: 59: 25.789ZPOST / orders? Before = 2 & limit = 30 {"product_id": "BTC-USD-0309", "order_id": "377454671037440"}

Так что эточто я пытался

BASE_URL = 'https://www.okex.com'.freeze

def base_api_endpoint
  url = URI.parse BASE_URL
  "#{url.scheme}://#{url.host}:#{url.port}"
end

def authenticated_request(method, url, options = {}, paginated: false)
  raise Exceptions::InvalidApiKey if @key.blank? || @secret.blank? || @passphrase.blank?
  response = rest_connection.run_request(method, URI.encode(url), nil, nil) do |req|
    if method == :post
      req.body = options.to_json
    else
      req.params.merge! options
    end
  end
def rest_connection
  @conn ||= new_rest_connection
end

TimestampRequestMiddleware = Struct.new(:app) do
  def call(env)
    env[:request_headers].merge!('OK-ACCESS-TIMESTAMP' => Time.now.utc.iso8601(3))
    app.call env
  end
end

SignRequestMiddleware = Struct.new(:app, :key, :secret, :passphrase) do
  def call(env)
    request_path = env[:url].path
    if env[:url].query.present?
      request_path += ('?' + env[:url].query)
    end
    timestamp = env[:request_headers]['OK-ACCESS-TIMESTAMP']
    method = env[:method].to_s.upcase
    what = "#{timestamp} + #{method} + #{request_path} + #{env.body}"
    decoded_secret = Base64.decode64(secret)
    mac  = OpenSSL::HMAC.digest('sha256', decoded_secret, what)
    sign = Base64.strict_encode64(mac)
    env[:request_headers].merge!('OK-ACCESS-KEY' => key, 'OK-ACCESS-SIGN' => sign, 'OK-ACCESS-TIMESTAMP' => timestamp, 'OK-ACCESS-PASSPHRASE' => passphrase)
    app.call env
  end
end

def new_rest_connection
  Faraday.new( base_api_endpoint, { ssl: { verify: false } }) do |conn|
    conn.use Market::OkexMarket::OkexCustomErrors, api_key: @key
    conn.request :json
    conn.response :json, content_type: /\bjson$/
    conn.response :logger, Logger.new(STDOUT) , bodies: true  if Rails.env.development?
    conn.use FaradayMiddleware::ParseJson, :content_type => /\bjson$/
    conn.use TimestampRequestMiddleware
    conn.use SignRequestMiddleware, @key, @secret, @passphrase
    conn.headers['Content-Type'] = 'application/json'
    conn.adapter :net_http
  end
end

def complete_balances
  data = authenticated_request(:get, '/api/spot/v3/accounts')
  data.map do |d|
    [
        d['currency'],
        {'available' => d['available'].to_f, 'onOrders' => d['hold'].to_f}
    ]
  end.to_h
end

Но когда я вызываю метод complete_balances, я получаю сообщение об ошибке от okex: {"code" => 30013, "message" => "Invalid Sign"} и не могупризнать, где я не прав.Может ли кто-нибудь помочь мне с этим?

1 Ответ

0 голосов
/ 13 марта 2019

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

...