如何在Windows Phone 8中获取HttpOnly cookies?

4
我正在一个Windows Phone 8 PCL项目中工作。我正在使用第三方REST API,并需要使用由该API发出的一些HttpOnly cookie。似乎无法从HttpClientHandler的CookieContainer获取/访问HttpOnly cookie,除非您使用反射或其他后门。
我需要获取这些cookie并在随后的请求中发送它们,否则我将无法使用此API - 我该怎么做?以下是我的当前请求代码:
提前感谢您的帮助。
//Some request
HttpRequestMessage request = new HttpRequestMessage();
HttpClientHandler handler = new HttpClientHandler();

//Cycle through the cookie store and add existing cookies for the susbsequent request
foreach (KeyValuePair<string, Cookie> cookie in CookieManager.Instance.Cookies)
{
            handler.CookieContainer.Add(request.RequestUri, new Cookie(cookie.Value.Name, cookie.Value.Value));
}

//Send the request asynchronously
HttpResponseMessage response = await httpClient.SendAsync(request);
response.EnsureSuccessStatusCode();

//Parse all returned cookies and place in cookie store
foreach (Cookie clientcookie in handler.CookieContainer.GetCookies(request.RequestUri))
{
     if (!CookieManager.Instance.Cookies.ContainsKey(clientcookie.Name))
                CookieManager.Instance.Cookies.Add(clientcookie.Name, clientcookie);
            else
                CookieManager.Instance.Cookies[clientcookie.Name] = clientcookie;
}

HttpClient httpClient = new HttpClient(handler);
2个回答

4
HttpOnly cookie 存储在 CookieContainer 中,但只是不可见。如果您将相同的 CookieContainer 实例设置为下一次请求,它将在那里设置隐藏的 cookie(只要请求是发送给指定的站点)。这种解决方案有效,直到您需要序列化和反序列化 CookieContainer 以恢复状态。一旦这样做,您就会丢失 CookieContainer 中隐藏的 HttpOnly cookie。因此,更长久的解决方案是直接使用套接字进行请求,将原始请求作为字符串读取,提取 cookie 并将其设置为下一个请求。以下是在 Windows Phone 8 中使用套接字的代码:
public async Task<string> Send(Uri requestUri, string request)
{
   var socket = new StreamSocket();
   var hostname = new HostName(requestUri.Host);
   await socket.ConnectAsync(hostname, requestUri.Port.ToString());

   var writer = new DataWriter(socket.OutputStream);
   writer.WriteString(request);
   await writer.StoreAsync();

   var reader = new DataReader(socket.InputStream) 
   { 
      InputStreamOptions = InputStreamOptions.Partial 
   };
   var count = await reader.LoadAsync(512);

    if (count > 0)
      return reader.ReadString(count);
    return null;
}

太棒了,正是我所需要的!谢谢。 - Nick

0
还有第二种可能-手动浏览响应头,使用一堆自定义代码抓取并解析Set-Cookie头。
当您要匹配和保存单个PHPSESSID cookie时(假设LatestResponse是包含网站响应的HttpResponseMessage),它看起来像这样:
if (LatestResponse.Headers.ToString().IndexOf("Set-Cookie:") != -1) try
        {
            string sid = LatestResponse.Headers.ToString();
            sid = sid.Substring(sid.IndexOf("Set-Cookie:"), 128);
                if (sid.IndexOf("PHPSESSID=") != -1)
                {
                    settings.Values["SessionID"] = SessionID = sid.Substring(sid.IndexOf("PHPSESSID=") + 10, sid.IndexOf(';') - sid.IndexOf("PHPSESSID=") - 10);
                    handler.CookieContainer.Add(new Uri("http://example.com", UriKind.Absolute), new System.Net.Cookie("PHPSESSID", SessionID));
                }
        } catch (Exception e) { 
            // your exception handling
        }

请注意,此代码将 cookie 插入到 CookieContainer 中,除非手动删除,否则该对象的生命周期内都会存在。如果您想将其包含在新对象中,只需提取正确的设置值并将其添加到新容器中即可。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接