0

我是一名初学者 C# 开发人员,我有点卡住了。

我有一个项目,我需要在发出 HTTP 请求时保留相同的会话 ID cookie。请求工作正常,我在 API 中创建了我需要的东西(它是一个货币兑换 API)。问题是,当我创建购买付款时,比如说 100 英镑,我会进入需要授权付款的屏幕。在这里,我的汇率有效期为 1.5 分钟。当时间结束时,费率会刷新。要锁定费率,我需要授权付款。当我授权时,我会进入屏幕等待付款。这里的汇率现在已锁定,但问题是汇率与我锁定的不同。该网站的所有者告诉我,这是因为创建付款和授权的请求上的会话 ID 不同。

这是来自 API 文档:

API 连接可以通过 cURL 等 HttpsRequest 组件建立。如果 cURL 库在所需语言版本中不可用,则替代方案应提供如下:

  1. 所有 cURL 查询/请求/数据传输都应仅使用 HTTPS 协议。
  2. 所有敏感信息必须通过POST方式发送;
  3. SSL 证书和 SSL 主机验证。它将防止 DNS 黑客攻击。参见 CURLOPT_SSL_VERIFYHOST 和 CURLOPT_SSL_VERIFYPEER
  4. 会话和 cookie 支持;

我找到的示例代码是在 PHP 中使用 Curl。这是我使用 LibCurlNet 想出的:

public class Http
{
     string _xmlResponse = string.Empty;

     private static Easy easy;
     private static Easy.WriteFunction wf = null;




    public string PerformRequest(string xml, string queryString, string url)
    {

        try
        {
            _xmlResponse = string.Empty;
            Curl.GlobalInit((int)CURLinitFlag.CURL_GLOBAL_ALL);
            easy = new Easy();

            wf = new Easy.WriteFunction(OnWriteData);
            easy.SetOpt(CURLoption.CURLOPT_URL, url);
            easy.SetOpt(CURLoption.CURLOPT_WRITEFUNCTION, wf);
            easy.SetOpt(CURLoption.CURLOPT_COOKIEFILE, HttpContext.Current.Request.MapPath("~/cookies.txt"));
            easy.SetOpt(CURLoption.CURLOPT_COOKIEJAR, HttpContext.Current.Request.MapPath("~/cookies.txt"));



            easy.SetOpt(CURLoption.CURLOPT_SSL_VERIFYPEER, true);
            easy.SetOpt(CURLoption.CURLOPT_SSL_VERIFYHOST, true);
            easy.SetOpt(CURLoption.CURLOPT_CAINFO, HttpContext.Current.Request.MapPath("~/ssl.crt"));
            easy.SetOpt(CURLoption.CURLOPT_HEADER, 0);
            easy.SetOpt(CURLoption.CURLOPT_FOLLOWLOCATION, true);
            easy.SetOpt(CURLoption.CURLOPT_USERAGENT, "xxx Web XML API");

            easy.SetOpt(CURLoption.CURLOPT_BUFFERSIZE, 65536);
            easy.SetOpt(CURLoption.CURLOPT_POSTFIELDS, CleanXML(xml));
            easy.Perform();
            easy.Cleanup();

            Curl.GlobalCleanup();
        }
        catch (Exception ex)
        {
            return ex.Message;
        }
        return _xmlResponse;
    }

    public Int32 OnWriteData(Byte[] buf, Int32 size, Int32 nmemb,
        Object extraData)
    {
        _xmlResponse = _xmlResponse + System.Text.Encoding.UTF8.GetString(buf);

        return size * nmemb;
    }

    private string CleanXML(string xml)
    {

        char[] sep = Environment.NewLine.ToArray();
        string[] lines = xml.Split(sep);
        StringBuilder sb = new StringBuilder();
        foreach (string line in lines)
        {
            sb.Append(line.Trim());
        }
        return sb.ToString();
    }

}

问题是 cookie.txt 会在我创建的每个连接中更新会话 ID。

带有 HttpWebRequest 的代码:

public class HttpV2
{
   static CookieCollection cookie = new CookieCollection();
   string responseFromServer;
   public string GetHttpResponse(string Url, string requestBody)
   {



       //WebRequest request = WebRequest.Create(Url);

       HttpWebRequest request = HttpWebRequest.CreateHttp(Url);

        X509Certificate Cert = X509Certificate.CreateFromCertFile(@"D:\www_root\xxxxxxxxxxx\xxxxx\ssl.crt");
        request.ClientCertificates.Add(Cert);
        request.Method = "POST";


       //HttpContext context = HttpContext.Current;
       request.CookieContainer = new CookieContainer();
       request.UserAgent = "TranferMate Web XML API";
       if (cookie != null)
       {

           request.CookieContainer.Add(cookie);

       }
       byte[] byteArray = Encoding.UTF8.GetBytes(requestBody);
       request.ContentType = "application/x-www-form-urlencoded";
       request.ContentLength = byteArray.Length;

       Stream dataStream = request.GetRequestStream();
       dataStream.Write(byteArray, 0, byteArray.Length);
       dataStream.Close();

       #region Get the response.
       using (WebResponse response = request.GetResponse())
       {
           if (requestBody.Contains("<FORCE_REFRESH>1</FORCE_REFRESH>"))
           {
               cookie = ((HttpWebResponse)response).Cookies;
           }
           if (((HttpWebResponse)response).StatusCode == HttpStatusCode.OK)
               using (Stream stream = response.GetResponseStream())
               {
                   if (stream != null)
                   {
                       using (StreamReader reader = new StreamReader(stream))
                       {
                           responseFromServer = reader.ReadToEnd();

                           reader.Close();
                       }
                       stream.Close();
                   }
               }
           response.Close();
       }
       #endregion

       return responseFromServer;
   }
}
4

1 回答 1

0

除了使用Curl,你能不使用内置HttpWebRequest类吗?HttpWebRequest有一个CookieContainer可以分配对象的CookieContainer属性。这个对象可以在请求之间重用,所以我认为它应该做你所追求的。

于 2013-09-04T11:00:26.610 回答