1

一段时间以来,我一直在努力为私有 GDAX 端点签名请求。我尝试过的所有操作都会导致 400 响应,并显示“签名无效”的消息。我已经多次阅读他们关于此事的文档,可以在这里找到。我当前的代码如下。我clj-http用于提出请求。我正在使用他们的/time端点响应作为时间戳,并且我正在使用pandect来生成 sha256 HMAC。在将其secret-decoded传递String.sha256-hmac. 我还使用检查了请求clj-http的调试标志。在我看来,我完全按照他们的指示行事,但肯定有问题。在这里发帖之前,我已经做了很多在线搜索。任何帮助将不胜感激。

(defn get-time
  []
  (-> (str (:api-base-url config) "/time")
      (http/get {:as :json})
      :body))

(defn- create-signature
  ([timestamp method path]
   (create-signature timestamp method path ""))
  ([timestamp method path body]
   (let [secret-decoded (b64/decode (.getBytes (:api-secret config)))
         prehash-string (str timestamp (clojure.string/upper-case method) path body)
         hmac (sha256-hmac prehash-string secret-decoded)]
      (-> hmac
          .getBytes
          b64/encode
          String.))))

(defn- send-signed-request 
  [method path & [opts]]
  (let [url (str (:api-base-url config) path)
        timestamp (long (:epoch (get-time)))
        signature (create-signature timestamp method path (:body opts))]
    (http/request
      (merge {:method method
              :url url
              :as :json
              :headers {"CB-ACCESS-KEY" (:api-key config)
                        "CB-ACCESS-SIGN" signature
                        "CB-ACCESS-TIMESTAMP" timestamp
                        "CB-ACCESS-PASSPHRASE" (:api-passphrase config)
                        "Content-Type" "application/json"}
              :debug true}
             opts))))

(defn get-accounts []
  (send-signed-request "GET" "/accounts"))

(send-signed-request "GET" "/accounts")))
4

1 回答 1

0

我已经弄清楚了这个问题。以防万一有人碰巧遇到这个非常具体的问题,我将发布解决方案。我的错误是我使用了sha256-hmacpandect 中的函数,它返回一个字符串 hmac,然后我将其转换为字节数组,对其进行 base64 编码,并将其转换回字符串。在这些转换中的某处,或者可能在 pandect 函数的转换中,值以错误的方式更改。

有效的是使用sha256-hmac*来自 pandect 的函数(注意星号),它返回一个原始字节数组 hmac,然后直接对结果进行 base64 编码,并将其转换为字符串。下面是更正后的工作代码片段,我可以使用它向私有 GDAX 端点发出请求。

(defn create-signature
  ([timestamp method path]
    (create-signature timestamp method path ""))
  ([timestamp method path body]
    (let [secret-decoded (b64/decode (.getBytes (:api-secret config)))
          prehash-string (str timestamp (clojure.string/upper-case method) path body)
          hmac (sha256-hmac* prehash-string secret-decoded)]
      (-> hmac
          b64/encode
          String.))))
于 2018-01-19T21:31:32.973 回答