none
一个在IE中使用的ActiveX控件,在向HTTP服务器发送请求的时候,如何共享IE的cookie? RRS feed

  • 问题

  • 有一个在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!

    2012年7月6日 3:26

答案

  • 打开请求的时候加了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
    2012年8月9日 13:33
    版主

全部回复

  • 参考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

    2012年7月8日 23:50
    版主
  • 我看了下,我的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
    2012年7月12日 10:12
  • 请专家再帮我看看,谢谢了。

    da jia hao!

    2012年8月7日 6:28
  • 用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

    2012年8月7日 12:53
    版主
  • fiddle不显示任何内容,只显示由IE发起的请求,通过我写的控件发起的HTTP请求,fiddler没有任何记录。。。。


    da jia hao!

    2012年8月8日 7:50
  • 你的控件要支持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

    2012年8月8日 14:08
    版主
  • 我在代码里面这样写:

    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!

    2012年8月9日 2:44
  • 打开请求的时候加了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
    2012年8月9日 13:33
    版主
  • 果然如此!在OpenRequest的时候指定INTERNET_FLAG_NO_COOKIES,随后调用HttpAddRequestHeaders的时候就OK了!在服务器的日志里面可以确认,客户端发送过来的Cookie的确就是我在程序里面写好的Cookie!

    da jia hao!

    2012年8月10日 2:09