简体   繁体   English

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

[英]How can I get HttpOnly cookies in Windows Phone 8?

I am working in a Windows Phone 8 PCL project. 我在Windows Phone 8 PCL项目中工作。 I am using a 3rd party REST API and I need to use a few HttpOnly cookies originated by the API. 我正在使用第三方REST API,我需要使用由API发起的一些HttpOnly cookie。 It seems like getting/accessing the HttpOnly cookies from HttpClientHandler's CookieContainer is not possible unless you use reflection or some other backdoor. 似乎从HttpClientHandler的CookieContainer获取/访问HttpOnly cookie似乎是不可能的,除非你使用反射或其他一些后门。

I need to get these cookies and send them in subsequent requests otherwise I am not going to be able to work with this API - how can I accomplish this? 我需要获取这些cookie并在后续请求中发送它们,否则我将无法使用此API - 我该如何实现这一目标? Here is what my current request code looks like: 以下是我当前的请求代码:

Thanks in advance. 提前致谢。

//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);

The HttpOnly cookie is inside the CookieContainer, it's only that is not exposed. HttpOnly cookie位于CookieContainer中,它只是不暴露。 If you set the same instance of that CookieContainer to the next request it will set the hidden cookie there (as long as the request is made to the same site the cookie specifies). 如果您将该CookieContainer的相同实例设置为下一个请求,它将在那里设置隐藏的cookie(只要请求到cookie指定的同一站点)。

That solution will work until you need to serialize and deserialize the CookieContainer because you are restoring state. 该解决方案将一直有效,直到您需要序列化和反序列化CookieContainer,因为您正在恢复状态。 Once you do that you lose the HttpOnly cookies hidden inside the CookieContainer. 一旦你这样做,你就会丢失隐藏在CookieContainer中的HttpOnly cookie。 So, a more permanent solution would be using Sockets directly for that request, read the raw request as a string, extract the cookie and set it to the next requests. 因此,更永久的解决方案是直接为该请求使用套接字,将原始请求作为字符串读取,提取cookie并将其设置为下一个请求。 Here's the code for using Sockets in Windows Phone 8: 这是在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;
}

There is also a second possibility - to manually go through response headers, grab and then parse Set-Cookie headers using a bunch of custom code. 还有第二种可能性 - 手动浏览响应头,抓取然后使用一堆自定义代码解析Set-Cookie头。

It looks something like that, when you are going to match and save a single PHPSESSID cookie (assume LatestResponse is your HttpResponseMessage containing website response): 它看起来像这样,当你要匹配并保存一个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
        }

Note this code inserts the cookie to CookieContainer for that object's life unless manually deleted. 请注意,除非手动删除,否则此代码CookieContainer Cookie插入CookieContainer以获取该对象的生命周期。 If you want to include it in a new object, just pull the right setting value and add it to your new container. 如果要将其包含在新对象中,只需拉出正确的设置值并将其添加到新容器中即可。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM