如何使用 C# 应用程序在本地保存 cookie?
How to save cookies locally using a C# app?
我有向特定域发出请求并获取响应 cookie 的 C# 代码。
现在,当我在 Internet Explorer 中访问同一个 URL 时,系统会提示我输入凭据,因为我的应用程序获得的 cookie 似乎没有像常规那样保存在 'Temporary Internet Files' 文件夹中存储 cookie。
那么即使我的本地 c# 应用程序已关闭,我如何存储 cookie 以供将来通过 IE 使用?
我确实在我的 response.cookies 中获得了有效的 cookie。
[添加了更多信息]
互联网浏览器 8
Visual Studio 2010
Windows 7 64位
这是我对 InternetSetCookieEx 的调用
我正在做的是在请求中使用 Cookie1 去 URL1,我在响应中得到更多的 cookie,这些 cookie 需要验证 URL2,URL2 收到cookie 并发送更多 cookie。现在,从 Web 浏览器控件发送了对 URL2 的单独调用,当在 Fiddler 上看到时,它似乎没有携带我从 response2 获得的 cookie。
[DllImport("wininet.dll", CharSet = CharSet.Auto, SetLastError = true, CallingConvention = CallingConvention.Cdecl)]
public static extern bool InternetSetCookieEx(string UrlName, string CookieName, string CookieData);
URL1 = "my.domain.com/page1.aspx";
URL2 = "my.domain.com/page2.aspx";
// Request to URL1
HttpWebRequest request1 = HttpWebRequest.Create(URL1) as HttpWebRequest;
request1.Method = "GET";
request1.Accept = "*/*";
request1.AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate;
request1.UserAgent = "CookieCreator";
request1.KeepAlive = true;
request1.AllowAutoRedirect = true;
Uri uri1 = new Uri(URL1);
request1.CookieContainer = new CookieContainer();
request1.CookieContainer.Add(new Cookie() { Name = "Cookie1", Value = "Some Value", Domain = uri1.Host });
HttpWebResponse response1 = (HttpWebResponse)request1.GetResponse();
//Request to URL2
HttpWebRequest request2 = HttpWebRequest.Create(URL2) as HttpWebRequest;
request2.Method = "GET";
request2.Accept = "application/x-ms-application, image/jpeg, application/xaml+xml, image/gif, image/pjpeg, application/x-ms-xbap, application/vnd.ms-excel, application/vnd.ms-powerpoint, application/msword, */*";
request2.AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate;
request2.UserAgent = "CookieCreator";
request2.KeepAlive = true;
request2.AllowAutoRedirect = true;
Uri uri = new Uri(URL2);
request2.CookieContainer = new CookieContainer();
//This sets session cookies, also adds the response cookie from URl1 into the request for URL2
foreach (Cookie cookie1 in response1.Cookies)
{
bool Output = InternetSetCookieEx(URL1, cookie1.Name, cookie1.Value);
request2.CookieContainer.Add(cookie1);
}
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
//This sets session cookies, hence will/should not be prompted for login credentials
foreach (Cookie cookie2 in response2.Cookies)
{
bool Output = InternetSetCookieEx(URL2, cookie.Name, cookie.Value);
}
我在使用时出现异常
bool Output = InternetSetCookieEx(URL1, cookie.Name, cookie.Value, "INTERNET_COOKIE_THIRD_PARTY");
异常
System.AccessViolationException was unhandled by user code
HResult=-2147467261 Message=Attempted to read or write protected
memory. This is often an indication that other memory is corrupt.
Source=Thomson.Reuters.AFO.Components.Excel StackTrace:
at Thomson.Reuters.AFO.Components.Excel.DFOCookieValidator.DFOCookieValidator.InternetSetCookieEx(String
UrlName, String CookieName, String CookieData, String flag)
at Thomson.Reuters.AFO.Components.Excel.DFOCookieValidator.DFOCookieValidator.ChartingCookieValidation(String
URL) in
C:\Codebase\DFO\AFO\Thomson.Reuters.AFO.Components.Excel\DFOCookieValidator\DFOCookieValidator.cs:line
180
at Thomson.Reuters.AFO.Components.Excel.AFOBrowser.AFOBrowserNewWindow.webBrowserNewWindow_Navigating(Object
sender, NavigatingCancelEventArgs e) in
C:\Codebase\DFO\AFO\Thomson.Reuters.AFO.Components.Excel\AFOBrowser\AFOBrowserNewWindow.xaml.cs:line
139
at System.Windows.Controls.WebBrowser.OnNavigating(NavigatingCancelEventArgs
e)
at MS.Internal.Controls.WebBrowserEvent.BeforeNavigate2(Object pDisp, Object& url, Object& flags, Object& targetFrameName, Object&
postData, Object& headers, Boolean& cancel) InnerException:
任何应用程序都可以为浏览器写入 cookie,但它会引入应考虑的问题。
首先是兼容性,不是谁都用同一个浏览器同一个系统。将 cookie 从应用程序传输到用户的浏览器将是一个难以维护的过程。
接下来,浏览器处理 cookie 的方式的任何更新都会破坏您的代码,并且您最终可能也会遇到损坏的浏览器。
即使您只是想为 IE 创建一个 cookie,用户也有不同的版本。
文件锁定,如果浏览器正在使用 cookie 文件,您可能无法在其上写入
用户覆盖,如果用户已经通过浏览器登录,为另一个用户创建 cookie 将简单地断开初始用户。
但要回答如何,IE 提供WinINet APIs and you can use InternetSetCookie or InternetSetCookieEx
对于 IE,使用这些方法将是最干净的方法。
On Windows Vista and above, Internet Explorer runs Internet content in Protected Mode, a sandbox with an isolated cookie store. In order to set a cookie in the Protected Mode sandbox from an external application running at Medium integrity (aka outside of Internet Explorer), you must use the IESetProtectedModeCookie function.
E10+ on Windows 8+ introduced Enhanced Protected Mode which uses AppContainers (rather than Integrity Levels) for isolation. EPM does not offer an API for interacting with cookies; IESetProtectedModeCookie will not set the cookie inside an AppContainer. (source)
但还是希望让用户自己重新登录。
显然它是我生成的会话 cookie,它不会存储在 IE cookie 存储中。因此,对同一个 domain/URL 的任何新 HTTP 请求都不会包含任何 cookie。
所以我所做的是创建一个新的 webbrowsercontrol,隐藏可见性,然后导航到那个 URL。我现在存储在 IE cookie 存储中的会话 cookie。
我有向特定域发出请求并获取响应 cookie 的 C# 代码。
现在,当我在 Internet Explorer 中访问同一个 URL 时,系统会提示我输入凭据,因为我的应用程序获得的 cookie 似乎没有像常规那样保存在 'Temporary Internet Files' 文件夹中存储 cookie。
那么即使我的本地 c# 应用程序已关闭,我如何存储 cookie 以供将来通过 IE 使用?
我确实在我的 response.cookies 中获得了有效的 cookie。
[添加了更多信息]
互联网浏览器 8 Visual Studio 2010 Windows 7 64位
这是我对 InternetSetCookieEx 的调用
我正在做的是在请求中使用 Cookie1 去 URL1,我在响应中得到更多的 cookie,这些 cookie 需要验证 URL2,URL2 收到cookie 并发送更多 cookie。现在,从 Web 浏览器控件发送了对 URL2 的单独调用,当在 Fiddler 上看到时,它似乎没有携带我从 response2 获得的 cookie。
[DllImport("wininet.dll", CharSet = CharSet.Auto, SetLastError = true, CallingConvention = CallingConvention.Cdecl)]
public static extern bool InternetSetCookieEx(string UrlName, string CookieName, string CookieData);
URL1 = "my.domain.com/page1.aspx";
URL2 = "my.domain.com/page2.aspx";
// Request to URL1
HttpWebRequest request1 = HttpWebRequest.Create(URL1) as HttpWebRequest;
request1.Method = "GET";
request1.Accept = "*/*";
request1.AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate;
request1.UserAgent = "CookieCreator";
request1.KeepAlive = true;
request1.AllowAutoRedirect = true;
Uri uri1 = new Uri(URL1);
request1.CookieContainer = new CookieContainer();
request1.CookieContainer.Add(new Cookie() { Name = "Cookie1", Value = "Some Value", Domain = uri1.Host });
HttpWebResponse response1 = (HttpWebResponse)request1.GetResponse();
//Request to URL2
HttpWebRequest request2 = HttpWebRequest.Create(URL2) as HttpWebRequest;
request2.Method = "GET";
request2.Accept = "application/x-ms-application, image/jpeg, application/xaml+xml, image/gif, image/pjpeg, application/x-ms-xbap, application/vnd.ms-excel, application/vnd.ms-powerpoint, application/msword, */*";
request2.AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate;
request2.UserAgent = "CookieCreator";
request2.KeepAlive = true;
request2.AllowAutoRedirect = true;
Uri uri = new Uri(URL2);
request2.CookieContainer = new CookieContainer();
//This sets session cookies, also adds the response cookie from URl1 into the request for URL2
foreach (Cookie cookie1 in response1.Cookies)
{
bool Output = InternetSetCookieEx(URL1, cookie1.Name, cookie1.Value);
request2.CookieContainer.Add(cookie1);
}
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
//This sets session cookies, hence will/should not be prompted for login credentials
foreach (Cookie cookie2 in response2.Cookies)
{
bool Output = InternetSetCookieEx(URL2, cookie.Name, cookie.Value);
}
我在使用时出现异常
bool Output = InternetSetCookieEx(URL1, cookie.Name, cookie.Value, "INTERNET_COOKIE_THIRD_PARTY");
异常
System.AccessViolationException was unhandled by user code
HResult=-2147467261 Message=Attempted to read or write protected memory. This is often an indication that other memory is corrupt.
Source=Thomson.Reuters.AFO.Components.Excel StackTrace: at Thomson.Reuters.AFO.Components.Excel.DFOCookieValidator.DFOCookieValidator.InternetSetCookieEx(String UrlName, String CookieName, String CookieData, String flag) at Thomson.Reuters.AFO.Components.Excel.DFOCookieValidator.DFOCookieValidator.ChartingCookieValidation(String URL) in C:\Codebase\DFO\AFO\Thomson.Reuters.AFO.Components.Excel\DFOCookieValidator\DFOCookieValidator.cs:line 180 at Thomson.Reuters.AFO.Components.Excel.AFOBrowser.AFOBrowserNewWindow.webBrowserNewWindow_Navigating(Object sender, NavigatingCancelEventArgs e) in C:\Codebase\DFO\AFO\Thomson.Reuters.AFO.Components.Excel\AFOBrowser\AFOBrowserNewWindow.xaml.cs:line 139 at System.Windows.Controls.WebBrowser.OnNavigating(NavigatingCancelEventArgs e) at MS.Internal.Controls.WebBrowserEvent.BeforeNavigate2(Object pDisp, Object& url, Object& flags, Object& targetFrameName, Object& postData, Object& headers, Boolean& cancel) InnerException:
任何应用程序都可以为浏览器写入 cookie,但它会引入应考虑的问题。
首先是兼容性,不是谁都用同一个浏览器同一个系统。将 cookie 从应用程序传输到用户的浏览器将是一个难以维护的过程。
接下来,浏览器处理 cookie 的方式的任何更新都会破坏您的代码,并且您最终可能也会遇到损坏的浏览器。 即使您只是想为 IE 创建一个 cookie,用户也有不同的版本。
文件锁定,如果浏览器正在使用 cookie 文件,您可能无法在其上写入
用户覆盖,如果用户已经通过浏览器登录,为另一个用户创建 cookie 将简单地断开初始用户。
但要回答如何,IE 提供WinINet APIs and you can use InternetSetCookie or InternetSetCookieEx
对于 IE,使用这些方法将是最干净的方法。
On Windows Vista and above, Internet Explorer runs Internet content in Protected Mode, a sandbox with an isolated cookie store. In order to set a cookie in the Protected Mode sandbox from an external application running at Medium integrity (aka outside of Internet Explorer), you must use the IESetProtectedModeCookie function.
E10+ on Windows 8+ introduced Enhanced Protected Mode which uses AppContainers (rather than Integrity Levels) for isolation. EPM does not offer an API for interacting with cookies; IESetProtectedModeCookie will not set the cookie inside an AppContainer. (source)
但还是希望让用户自己重新登录。
显然它是我生成的会话 cookie,它不会存储在 IE cookie 存储中。因此,对同一个 domain/URL 的任何新 HTTP 请求都不会包含任何 cookie。
所以我所做的是创建一个新的 webbrowsercontrol,隐藏可见性,然后导航到那个 URL。我现在存储在 IE cookie 存储中的会话 cookie。