首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Rails和net/https的FTX.com REST后身份验证失败

Rails和net/https的FTX.com REST后身份验证失败
EN

Stack Overflow用户
提问于 2021-11-14 15:46:55
回答 2查看 577关注 0票数 1

希望能得到一些帮助,因为这个让我很困惑.

我在FTX.com创建了一个用户帐户和API凭据。

他们有一个有趣的Auth设置,详细介绍如下:https://docs.ftx.com/?python#authentication

它们只为python、javascript和c#提供代码示例,但我需要在RoR应用程序上实现集成。

下面是一个链接,它还为GET和POST调用提供了一个示例:https://blog.ftx.com/blog/api-authentication/

我在用:

代码语言:javascript
复制
ruby '3.0.1'

gem 'rails', '~> 6.1.4', '>= 6.1.4.1'

还有,

代码语言:javascript
复制
require 'uri'
require 'net/https'
require 'net/http'
require 'json'

我获得了用于GET呼叫的身份验证,如下所示:

代码语言:javascript
复制
def get_market
 get_market_url = 'https://ftx.com/api/markets/BTC-PERP/orderbook?depth=20'

 api_get_call(get_market_url)
end
代码语言:javascript
复制
def api_get_call(url)
    ts = (Time.now.to_f * 1000).to_i

    signature_payload = "#{ts}GET/api/markets"

    key = ENV['FTX_API_SECRET']
    data = signature_payload
    digest = OpenSSL::Digest.new('sha256')

    signature = OpenSSL::HMAC.hexdigest(digest, key, data)

    headers = {
      'FTX-KEY': ENV['FTX_API_KEY'],
      'FTX-SIGN': signature,
      'FTX-TS': ts.to_s
    }
    uri = URI.parse(url)
    http = Net::HTTP.new(uri.host, uri.port)
    http.read_timeout = 1200
    http.use_ssl = true
    rsp = http.get(uri, headers)
    JSON.parse(rsp.body)
  end

这很好,我得到了正确的回答:

代码语言:javascript
复制
=>
{"success"=>true,
"result"=>
{"bids"=>
[[64326.0, 2.0309],
...
[64303.0, 3.1067]],
"asks"=>
[[64327.0, 4.647],
...
[64352.0, 0.01]]}}

但是,对于POST调用,我似乎无法正确地进行身份验证(尽管据我所知,我正在正确地执行说明)。我使用以下方法:

代码语言:javascript
复制
  def create_subaccount
    create_subaccount_url = 'https://ftx.com/api/subaccounts'

    call_body =
      {
        "nickname": "sub2",
      }.to_json

    api_post_call(create_subaccount_url, call_body)
  end
代码语言:javascript
复制
  def api_post_call(url, body)
    ts = (Time.now.to_f * 1000).to_i

    signature_payload = "#{ts}POST/api/subaccounts#{body}"

    key = ENV['FTX_API_SECRET']
    data = signature_payload
    digest = OpenSSL::Digest.new('sha256')

    signature = OpenSSL::HMAC.hexdigest(digest, key, data)

    headers = {
      'FTX-KEY': ENV['FTX_API_KEY'],
      'FTX-SIGN': signature,
      'FTX-TS': ts.to_s
    }

    uri = URI.parse(url)
    http = Net::HTTP.new(uri.host, uri.port)
    http.read_timeout = 1200
    http.use_ssl = true
    request = Net::HTTP::Post.new(uri, headers)
    request.body = body
    response = http.request(request)

    JSON.parse(response.body)
  end

还尝试通过request[]直接传递标头:

代码语言:javascript
复制
  def api_post_call(url, body)
    ts = (Time.now.to_f * 1000).to_i

    signature_payload = "#{ts}POST/api/subaccounts#{body}"

    key = ENV['FTX_API_SECRET']
    data = signature_payload
    digest = OpenSSL::Digest.new('sha256')

    signature = OpenSSL::HMAC.hexdigest(digest, key, data)

    uri = URI.parse(url)
    http = Net::HTTP.new(uri.host, uri.port)
    http.read_timeout = 1200
    http.use_ssl = true
    request = Net::HTTP::Post.new(uri)
    request['FTX-KEY'] = ENV['FTX_API_KEY']
    request['FTX-SIGN'] = signature
    request['FTX-TS'] = ts.to_s
    request.body = body
    response = http.request(request)

    JSON.parse(response.body)
  end

这是错误响应:=> {"success"=>false, "error"=>"Not logged in: Invalid signature"}

我的感觉是,在通过HMAC生成签名之前,在signature_payload中添加主体是问题所在..:signature_payload = "#{ts}POST/api/subaccounts#{body}"

这样想是因为,如果我在这里省略了#{body},比如:signature_payload = "#{ts}POST/api/subaccounts",响应是:=> {"success"=>false, "error"=>"Missing parameter nickname"}

我使用不同的net/https示例尝试了几次设置POST调用方法的迭代,但是没有成功.我也联系了FTX的支持,但没有回应。

如果有人对我在这里做错了什么有洞察力的话,你会真的很感激吗?

EN

回答 2

Stack Overflow用户

发布于 2022-04-06 11:31:08

尝试以下标题

代码语言:javascript
复制
headers = {
      'FTX-KEY': ENV['FTX_API_KEY'],
      'FTX-SIGN': signature,
      'FTX-TS': ts.to_s,
      'Content-Type' => 'application/json',
      'Accepts' => 'application/json',
    }
票数 0
EN

Stack Overflow用户

发布于 2022-07-05 13:03:04

下面是一个用于检索FTX子帐户的类的工作示例。为了你自己的目的而修改。我用HTTParty。

代码语言:javascript
复制
class Balancer
  require 'uri'
  require "openssl"
  include HTTParty

  def get_ftx_subaccounts
    method = 'GET'
    path = '/subaccounts'

    url = "#{ENV['FTX_BASE_URL']}#{path}"
    return HTTParty.get(url, headers: headers(method, path, ''))        
  end

  def headers(*args)
    {
      'FTX-KEY' => ENV['FTX_API_KEY'],
      'FTX-SIGN' => signature(*args),
      'FTX-TS' => ts.to_s,
      'Content-Type' => 'application/json',
      'Accepts' => 'application/json',
    }
  end

  def signature(*args)
    OpenSSL::HMAC.hexdigest(digest, ENV['FTX_API_SECRET'], signature_payload(*args))
  end

  def signature_payload(method, path, query)
    payload = [ts, method.to_s.upcase, "/api", path].compact
    
    if method==:post
      payload << query.to_json
    elsif method==:get
      payload << ("?" + URI.encode_www_form(query))
    end unless query.empty?

    payload.join.encode("UTF-8")
  end

  def ts
    @ts ||= (Time.now.to_f * 1000).to_i
  end

  def digest
    @digest ||= OpenSSL::Digest.new('sha256')
  end

end

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/69964624

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档