2013-03-22 69 views
11

我有一个应用程序通过HTTPS向API发送用户名和密码。该API返回HTTPOnly cookie。在Windows Phone上保留HTTPOnly Cookie

这意味着cookie对代码“不可见”,但仍然存在并将在随后的请求中发送到服务器。

Set-Cookie头从HttpWebResponse.Headers剥离和cookie不出现在HttpWebResponse.Cookie S或所述HttpWebRequest.CookieContainer。但是,如果后续请求使用相同的HttpWebRequest.CookieContainer进行发送,则会将其发送到服务器,但代码无法访问它们。

据我所知,这使得他们无法以任何方式进行序列化或保存。似乎做这项工作的唯一方法是每次缓存实际的用户名和密码并再次登录。

有什么我失踪?

+0

可以序列化整个'CookieContainer'(http://answers.flyppdevportal.com/categories/metro/csharpvb.aspx?id=d214c388-41de-44b7-8260-9e21f3fcb859),并在需要时重新使用整个容器吗? – keyboardP 2013-04-06 13:46:11

+0

您无法操作httponly cookie。只有在您发送http请求时才会修改它们。这对于服务器和客户端之间的安全通信至关重要。所以你所面对的这种行为是正常的。 – user568109 2013-04-06 14:25:48

+0

@keyboardP如果您将CookieContainer序列化,则在反序列化时不再发送Cookie。 – zi3guw 2013-04-06 15:29:59

回答

3

您将不得不使用反射来查看存储在cookie容器中的Cookie。

使用类似这样的东西来看看你有什么,然后你可以尝试子类来访问你想要的数据,或者通过在存储器中存储cookie的过程,从容器中删除它,然后将其添加为普通Cookie

public List<Cookie> GetAllCookies(CookieContainer cc) 
    { 
     List<Cookie> lstCookies = new List<Cookie>(); 

     Hashtable table = (Hashtable)cc.GetType().InvokeMember("m_domainTable", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.GetField | System.Reflection.BindingFlags.Instance, null, cc, new object[] { }); 

     foreach (var pathList in table.Values) 
     { 
      SortedList lstCookieCol = (SortedList)pathList.GetType().InvokeMember("m_list", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.GetField | System.Reflection.BindingFlags.Instance, null, pathList, new object[] { }); 
      foreach (CookieCollection colCookies in lstCookieCol.Values) 
       foreach (Cookie c in colCookies) lstCookies.Add(c); 
     } 

     return lstCookies; 
    } 
    public string ShowAllCookies(CookieContainer cc) 
    { 
     StringBuilder sb = new StringBuilder(); 
     List<Cookie> lstCookies = GetAllCookies(cc); 
     sb.AppendLine("=========================================================== "); 
     sb.AppendLine(lstCookies.Count + " cookies found."); 
     sb.AppendLine("=========================================================== "); 
     int cpt = 1; 
     foreach (Cookie c in lstCookies) 
      sb.AppendLine("#" + cpt++ + "> Name: " + c.Name + "\tValue: " + c.Value + "\tDomain: " + c.Domain + "\tPath: " + c.Path + "\tExp: " + c.Expires.ToString()); 

     return sb.ToString(); 
    } 
+0

当使用反射访问Windows Phone上的非公共类型时,您没有发现MethodAccessException?每次我尝试这样做时都失败 – calum 2013-04-13 10:01:32

+0

好catch。internal和protected应该是可以的,但是私人的肯定不是。查看CookieContainer的源代码,这应该工作,否则它将是一个遮罩建立一个基于源代码的自定义cookie容器类,并利用它来代替。 – 2013-04-13 10:17:19

+0

我甚至不能编译WP8上的这段代码(散列表,SortedList都丢失了)。 – altso 2013-08-13 13:40:55

1

您也可以尝试使用TCP套接字直接获取Cookie。下面是我对类似问题的回答:https://stackoverflow.com/a/21737087/262036

一旦得到响应,您就会分析字符串以搜索cookie并获取该值。之后,您可以在CookieContainer中创建一个不是HttpOnly的新cookie,并在接下来的请求中使用它。