积极答复者
一个在IE中使用的ActiveX控件,在向HTTP服务器发送请求的时候,如何共享IE的cookie?

问题
-
有一个在IE中使用的ActiveX控件,会通过WinINet API向服务器发送下载或者上传数据的请求。服务器是需要登录的,但实际使用中我发现只要IE登录了,那么控件不需要发送用户名和密码就能够正常访问服务器,这很好。说明控件是能够自动继承IE的会话。
但是,如果换成其他一些使用IE内核的浏览器,例如“360安全浏览器”,就不行了,控件访问服务器的时候出现用户身份未验证的错误。于是我就想通过将当前IE的cookie附加到控件的HTTP请求HEADER里面,这样理论上应该能够解决问题,代码如下:
hInet = InternetOpen( L"cow_shit", INTERNET_OPEN_TYPE_DIRECT, NULL, NULL, 0 ); hConnect = InternetConnect( hInet, m_serverURL, m_serverPort, NULL, NULL, INTERNET_SERVICE_HTTP, 0, 0 ); hRequest = HttpOpenRequest( hConnect, L"POST", lpszServerPath, HTTP_VERSION, NULL, NULL, INTERNET_FLAG_KEEP_CONNECTION | INTERNET_FLAG_NO_CACHE_WRITE | INTERNET_FLAG_FORMS_SUBMIT, 0 ); //添加“Cookie”标头 CString csCookie=L""; LPOLECLIENTSITE pClientSite = GetClientSite(); IServiceProvider *pISP; IWebBrowser2 *pIE; HRESULT hr; IDispatch *pDisp = NULL; IDispatch *pElementDispatch = NULL; IHTMLDocument2 *pDoc = NULL; hr = pClientSite->QueryInterface( IID_IServiceProvider, (void **)&pISP ); if( SUCCEEDED(hr) && ( pISP != NULL ) ) { hr = pISP->QueryService( IID_IWebBrowserApp, IID_IWebBrowser2, (void **)&pIE ); if( SUCCEEDED(hr) && ( pIE != NULL ) ) { pIE->get_Document( &pDisp ); hr = pDisp->QueryInterface( IID_IHTMLDocument2, (void **)&pDoc ); if( SUCCEEDED(hr) && ( pDoc != NULL ) ) { BSTR bstrCookie; hr = pDoc->get_cookie(&bstrCookie); if(hr == S_OK) { csCookie = bstrCookie; SysFreeString(bstrCookie); pDoc->Release(); pIE->Release(); pISP->Release(); } } else { MessageBox( L"Query IHTMLDocument2 error" ); pIE->Release(); pISP->Release(); } } else { MessageBox( L"Query IWebBrowserApp service error" ); pISP->Release(); } } csCookie=L"Cookie: "+csCookie; rrr = HttpAddRequestHeaders( hRequest, (LPCTSTR)csCookie, csCookie.GetLength(), HTTP_ADDREQ_FLAG_REPLACE ); //发送请求 rrr = HttpSendRequestEx( hRequest, &ib, NULL, HSR_INITIATE, 0 );
按理说我已经把当前IE的cookie附加到请求的HEADER里面了,应该能够正常通过验证,但仍然不行,请问我这样添加HEADER正确吗?
da jia hao!
答案
-
打开请求的时候加了INTERNET_FLAG_NO_COOKIES吗?如果没有加的话应该会自动生成cookie头,覆盖你的cookie设置的。你也可以改用InternetSetCookie,这个会影响WinInet自动生成cookie头
The following is signature, not part of post
Please mark the post answered your question as the answer, and mark other helpful posts as helpful, so they will appear differently to other users who are visiting your thread for the same problem.
Visual C++ MVP- 已标记为答案 liubin 2012年8月10日 2:08
全部回复
-
参考http://www.codeproject.com/Articles/38616/Retrieve-HttpOnly-Session-Cookie-in-WebBrowser
The following is signature, not part of post
Please mark the post answered your question as the answer, and mark other helpful posts as helpful, so they will appear differently to other users who are visiting your thread for the same problem.
Visual C++ MVP- 已建议为答案 i1friend 2012年7月9日 8:43
- 已标记为答案 Elegentin XieModerator 2012年7月11日 9:14
- 取消答案标记 liubin 2012年8月7日 6:28
-
我看了下,我的cookie并不是“HttpOnly”的,通过IE的F12工具可以看到:
方向 键 值 截止期限 域 路径 安全 仅 HTTP
已发送 DomAuthSessId D55FA490B76868EBF109ECF60682C8AB而且我用get_cookie方法获取得到的cookie是正确的,它和我直接在IE里面用JavaScript:document.cookie返回而结果是完全一样的。
是不是我附加到header里面的程序有什么不对的地方呢?
哦,对了,在发送cookie的时候,是否需要在前面加上“Cookie:”的字符串?我的代码里面是加了的:
csCookie=L"Cookie: "+csCookie; rrr = HttpAddRequestHeaders( hRequest, (LPCTSTR)csCookie, csCookie.GetLength(), HTTP_ADDREQ_FLAG_REPLACE ); //发送请求 rrr = HttpSendRequestEx( hRequest, &ib, NULL, HSR_INITIATE, 0 );
da jia hao!
- 已编辑 liubin 2012年7月12日 10:15
-
用fiddler看看header有什么不同
The following is signature, not part of post
Please mark the post answered your question as the answer, and mark other helpful posts as helpful, so they will appear differently to other users who are visiting your thread for the same problem.
Visual C++ MVP -
你的控件要支持IE里的代理服务器设置……fiddler运行的时候会改代理设置到自己的代理服务器
The following is signature, not part of post
Please mark the post answered your question as the answer, and mark other helpful posts as helpful, so they will appear differently to other users who are visiting your thread for the same problem.
Visual C++ MVP -
我在代码里面这样写:
CString csCookie=L"DomAuthSessId=08302CA38B5E8857490583983DCC7A4D";//获取得到的document.cookie csCookie=L"Cookie: "+csCookie+";liubin=你好;qiqi=大家好\r\n";//我追加了自己的一些数据上去 //请问这样添加Header是否正确? rrr = HttpAddRequestHeaders( hRequest, (LPCTSTR)csCookie, csCookie.GetLength(), HTTP_ADDREQ_FLAG_REPLACE|HTTP_ADDREQ_FLAG_ADD );
结果通过fiddler,我发现最终发送给服务器的Cookie不包含我自己追加的那部分内容,是否添加CookieHeader的方法不正确,还是别的什么原因?
da jia hao!
-
打开请求的时候加了INTERNET_FLAG_NO_COOKIES吗?如果没有加的话应该会自动生成cookie头,覆盖你的cookie设置的。你也可以改用InternetSetCookie,这个会影响WinInet自动生成cookie头
The following is signature, not part of post
Please mark the post answered your question as the answer, and mark other helpful posts as helpful, so they will appear differently to other users who are visiting your thread for the same problem.
Visual C++ MVP- 已标记为答案 liubin 2012年8月10日 2:08