使用HTTP标头参数发布请求

时间:2017-10-20 10:34:59

标签: ios swift rest http-headers http-post

我想使用Bittrex api。我已经阅读了他们的api文档。有如下解释。

  

对于此版本,我们使用标准HMAC-SHA512签名。附加 apikey   和 nonce 到您的请求并计算HMAC哈希并包含它   在 apisign 标题下。

$apikey='xxx';
$apisecret='xxx';
$nonce=time();
$uri='https://bittrex.com/api/v1.1/market/getopenorders?apikey='.$apikey.'&nonce='.$nonce;
$sign=hash_hmac('sha512',$uri,$apisecret);
$ch = curl_init($uri);
curl_setopt($ch, CURLOPT_HTTPHEADER, array('apisign:'.$sign));
$execResult = curl_exec($ch);
$obj = json_decode($execResult);

我想用Swift做这件事。但我不想使用Alamofire。 我写了一个代码。我想我正在做的一切,但是我收到了以下错误。

{
    message = "APISIGN_NOT_PROVIDED";
    result = "<null>";
    success = 0;
}

我用Delphi编写了类似的代码。它工作正常。所以APIKEY没有问题。当我在Delphi中使用相同的参数时,会生成相同的SecretHex。所以加密没有问题。

我想,我不能用标题做Post Request。 我找不到错。你能帮我吗?

func getBalances()
    {
        let apiKeySTR = "01235xxxxxx"
        let secretSTR = "41691xxxxxx"

        let path = "https://bittrex.com/api/v1.1/account/"
        let timeInterval = NSDate().timeIntervalSince1970
        let epochtime = String(floor(timeInterval))

        let urlFull = path + "getbalances" + "?" + "apikey=" + apiKeySTR + "&" + "nonce=" + epochtime

        let secretUInt8 : [UInt8] = Array(urlFull.utf8)
        var secretKey : [UInt8]?

        do {
            try secretKey = HMAC(key: secretSTR, variant: .sha512).authenticate(secretUInt8)
        } catch {
            print ("Error")
        }

        let secretHex = secretKey?.toHexString() ?? ""

        guard let url = URL(string: urlFull) else { return }
        var request = URLRequest(url: url)
        request.addValue("apising", forHTTPHeaderField: (secretHex))
        request.httpMethod = "POST"

        let session = URLSession.shared
        session.dataTask(with: request) { (data, response, error) in
            if let response = response {
                print(response)
            }

            if let data = data {
                do {
                    let json = try JSONSerialization.jsonObject(with: data, options: [])
                    print(json)
                } catch {
                    print(error)
                }
            }

            }.resume()
    }

1 个答案:

答案 0 :(得分:3)

首先关闭...... 你有一个错字:

request.addValue("apising", forHTTPHeaderField: (secretHex))

我相信apisign,而不是&#34; apising&#34;,对吧?

以下是使用标题和正文创建REST API请求的概述。您可以根据需要更新此方法:

1)创建URLRequest

    var request = URLRequest(url: requestURL)

2)设置标题和http方法:

    request.allHTTPHeaderFields = ["Authentication" : "Bearer XYZ..."]
    request.httpMethod = "POST"

3)设置请求正文:

    // parameters is a simple [String:String] dictionary, just as header
    let jsonData = try? JSONSerialization.data(withJSONObject: parameters)
    request.httpBody = jsonData

完整示例:

  public enum RESTMethod:String {
       case get = "GET"
       case post = "POST"
       case put = "PUT"
  }

  public func sendRequest(_ url: String,
                        method: RESTMethod,
                        headers: [String : String],
                        parameters: [String : Any],
                        completionHandler: @escaping (Data?, URLResponse?, Error?) -> Void) -> URLSessionTask! {
    let requestURL: URL
    if method == .get {
        let parameterString = parameters.stringFromHttpParameters()
        requestURL = URL(string:"\(url)?\(parameterString)")!
    } else {
        requestURL = URL(string: url)!
    }


    var request = URLRequest(url: requestURL)
    request.allHTTPHeaderFields = headers
    request.httpMethod = method.rawValue
    if method == .post {
        let jsonData = try? JSONSerialization.data(withJSONObject: parameters)
        request.httpBody = jsonData
    }
    request.timeoutInterval = 60


    let task = URLSession.shared.dataTask(with: request) { (data, response, error) in

        completionHandler(data,response,error)
    }

    task.resume()

    return task

}


extension Dictionary {

/// Build string representation of HTTP parameter dictionary of keys and objects

func stringFromHttpParameters() -> String {
    let parameterArray = self.map { (key, value) -> String in
        let percentEscapedKey = (key as! String).addingPercentEncoding(withAllowedCharacters: CharacterSet.urlQueryAllowed)
        let percentEscapedValue = (value as? String ?? "\(value)").addingPercentEncodingForURLQueryValue()!
        return "\(percentEscapedKey)=\(percentEscapedValue)"
    }

    return parameterArray.joined(separator: "&")
}

}

用法:

sendRequest("http://yourserver",
             method: .get, // .post or .put
             headers: [],
             parameters: [],
             completionHandler: { (data, response, error) in

   // Handle response here

})