0

私は初心者の C# 開発者で、少し行き詰まっています。

HTTP リクエストを行うときに同じセッション ID Cookie を保持する必要があるプロジェクトがあります。リクエストは正常に機能します。API (通貨交換 API) で必要なものを作成します。問題は、購入するための支払いを作成するときに、支払いを承認する必要がある画面に移動するとします。ここには、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 のサポート。

私が見つけたサンプル コードは、Curl を使用した PHP でした。これは、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