2013-04-30 66 views
4

我在Windows Phone 8 PCL項目中工作。我正在使用第三方REST API,我需要使用由API發起的一些HttpOnly Cookie。看起來像從HttpClientHandler的CookieContainer獲取/訪問HttpOnly cookie是不可能的,除非您使用反射或其他後門。如何在Windows Phone 8中獲得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); 

回答

4

HttpOnly cookie位於CookieContainer內部,只是它沒有公開。如果您將CookieContainer的同一個實例設置爲下一個請求,它將在那裏設置隱藏的cookie(只要請求發送到cookie指定的同一個站點)。

該解決方案將工作,直到你需要序列化和反序列化CookieContainer,因爲你正在恢復狀態。一旦你這樣做了,你就會失去CookieContainer中隱藏的HttpOnly cookies。因此,更持久的解決方案是直接使用套接字作爲請求,將原始請求作爲字符串讀取,提取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; 
} 
+0

太棒了,正是我所需要的!謝謝。 – Nick 2014-04-13 15:27:37

0

也有第二種可能性 - 手動完成響應頭,搶,然後解析使用大量的自定義代碼設置Cookie頭。

它看起來類似的東西,當你要匹配,並且保存單個PHPSESSID餅乾(假設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爲對象的生活,除非手動刪除。如果你想將它包含在一個新的對象中,只需拉出正確的設置值並將其添加到新的容器中即可。

相關問題