【问题标题】:How to make signed API call in Swift如何在 Swift 中进行签名 API 调用
【发布时间】:2021-06-29 11:30:15
【问题描述】:

我正在尝试使用 HMAC SHA256 签名进行签名 API 请求。

如何提出已签名的请求?我无法生成正确的签名:

{"code":-1022,"msg":"此请求的签名无效。"}

  static func binanceAccountSnapshot(timeStamp: Int) {
        
        let semaphore = DispatchSemaphore (value: 0)
        let urlWithoutSignature = "https://api.binance.com/sapi/v1/capital/config/getall?timestamp=\(timeStamp)"
        let secretString = "aN345refdcx78iygkhbrefdoyilhukB6prefd98uoixjk(api secret)"
        let key = SymmetricKey(data: secretString.data(using: .utf8)!)
        
        let signature = HMAC<SHA256>.authenticationCode(for: urlWithoutSignature.data(using: .utf8)!, using: key)
        let signatureString = Data(signature).map { String(format: "%02hhx", $0) }.joined()
         
        var request = URLRequest(url: URL(string: "https://api.binance.com/sapi/v1/capital/config/getall?timestamp=\(timeStamp)&signature=\(signatureString)")!,timeoutInterval: Double.infinity)
        request.addValue("application/json", forHTTPHeaderField: "Content-Type")
        request.addValue("p4t98weflsudichjkxwtrfsduoxhckjnwe8isdokjx(api key)", forHTTPHeaderField: "X-MBX-APIKEY")
        request.httpMethod = "GET"
         
        let task = URLSession.shared.dataTask(with: request) { data, response, error in
            guard let data = data else {
                print(String(describing: error))
                semaphore.signal()
                return
            }
            print(String(data: data, encoding: .utf8)!)
            semaphore.signal()
        }
        task.resume()
    }

【问题讨论】:

  • 通常,您不会使用 ? 而是使用 &amp; 分隔 URL 参数。 ? if 将请求的其余部分和 url 表单中的参数分开。您可以使用QueryItem 这样做。
  • 现在,为您解决问题。在文档中,有一个 Postman 集合 binance-docs.github.io/apidocs/spot/en/#postman-collections,您可以在其中将其添加到 POSTMAN。 Postman 可以生成代码,所以你可以让 POSTMAN 生成 Swift 代码(作为初学者),看看它是如何完成的,然后复制(使用更好的 Swift 代码,因为它不是漂亮的代码),但你会决定把参数放在哪里(请求、标头等)
  • 关于如何使用您的私钥,我想在阅读binance-docs.github.io/apidocs/spot/en/#endpoint-security-type 后应该在 HTTP 标头中(可以通过 Postman 示例确认)。但实际上binance-docs.github.io/apidocs/spot/en/… 会是一个更好的链接/文档来阅读如何获得它。因为“GET /sapi/v1/accountSnapshot (HMAC SHA256)”和“预期输出”根本没有帮助。
  • 谢谢,这真的很有用。如何创建签名? Postman 会在每个请求上自动生成一个,所以我需要知道如何在 Swift 中生成它
  • 查看文档以了解哪些参数。其余的寻找 Swift 如何处理 HMac 256。很多关于此的问题。

标签: json swift api decodable binance


【解决方案1】:

您的代码几乎可以工作,签名的字符串应该只是 url 的参数,而不是整个 url(字符串应该只是 url 中 ? 之后的那些字符)

  static func binanceAccountSnapshot(timeStamp: Int) {
        
        let semaphore = DispatchSemaphore (value: 0)
        let params = timestamp=\(timeStamp)
        let urlWithoutSignature = "https://api.binance.com/sapi/v1/capital/config/getall?\(params)"
        let secretString = "aN345refdcx78iygkhbrefdoyilhukB6prefd98uoixjk(api secret)"
        let key = SymmetricKey(data: secretString.data(using: .utf8)!)
        
        let signature = HMAC<SHA256>.authenticationCode(for: params.data(using: .utf8)!, using: key)
        let signatureString = Data(signature).map { String(format: "%02hhx", $0) }.joined()
         
        var request = URLRequest(url: URL(string: "https://api.binance.com/sapi/v1/capital/config/getall?timestamp=\(timeStamp)&signature=\(signatureString)")!,timeoutInterval: Double.infinity)
        request.addValue("application/json", forHTTPHeaderField: "Content-Type")
        request.addValue("p4t98weflsudichjkxwtrfsduoxhckjnwe8isdokjx(api key)", forHTTPHeaderField: "X-MBX-APIKEY")
        request.httpMethod = "GET"
         
        let task = URLSession.shared.dataTask(with: request) { data, response, error in
            guard let data = data else {
                print(String(describing: error))
                semaphore.signal()
                return
            }
            print(String(data: data, encoding: .utf8)!)
            semaphore.signal()
        }
        task.resume()
    }

【讨论】:

    猜你喜欢
    • 2017-07-10
    • 2014-08-10
    • 2016-06-10
    • 2018-11-06
    • 1970-01-01
    • 1970-01-01
    • 2022-08-02
    • 1970-01-01
    • 2018-09-26
    相关资源
    最近更新 更多