用Wininet以Https的post方式登录

        整个过程大概是这样的:发送http请求报文到服务器,报文的数据体中带有账号密码;服务器接受处理后返回响应报文;根据响应报文的状态码判断登录是否成功,通过读取返回报文的首部行获取所需的信息。我这里是通过Location获取返回的cookie信息,用webBroswer登录时加载cookie即可。

大致的代码如下:

// strUrl:登录检测的地址;postData:发送的账号密码字符串(如:name==xxx&password=xxx);strCookie:获取的cookie字符串

int Login(const CString& strUrl, const CString& postData, CString& strCookie)
{

    //检测网路状态

    if (!InternetCheckConnection(strUrl, FLAG_ICC_FORCE_CONNECTION, 0))
    {
        return -1;
    }

   //加载Wininet函数

    HINTERNET hInternet = InternetOpen(_T("HTTP Request..."), INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0);
    if (hInternet == NULL)
    {
        InternetCloseHandle(hInternet);
        return 0;
    }

   //解析出主机和uri地址
    CString strServer, strUri, strHeader, strRet;
    unsigned short nPort;
    DWORD dwServiceType;
    AfxParseURL(strUrl, dwServiceType, strServer, strUri, nPort);

   //建立连接,第二个参数是服务器主机地址;第三个参数是因为连接https;
    HINTERNET hConnect = InternetConnect(hInternet, strServer, INTERNET_DEFAULT_HTTPS_PORT, NULL, NULL, INTERNET_SERVICE_HTTP, 0, 0);  
    if(!hConnect)  
    {
        InternetCloseHandle(hInternet);
        return 0;
    }

    //打开一个请求,第三个参数是uri;INTERNET_FLAG_SECURE参数是https加密
    HINTERNET hRequest = HttpOpenRequest(hConnect, _T("POST"), strUri, _T("HTTP/1.1"), NULL, NULL, INTERNET_FLAG_SECURE, 0);
    if(!hRequest)
    {
        InternetCloseHandle(hInternet);
        InternetCloseHandle(hConnect);
        return 0;
    }

   //首部行信息,我是都放在一个Cstring中了,主要是Content-Type参数要设,每个首部行参数之间加\r\n;
    char* data = TcUtility::StringToChar(postData, CP_UTF8);

    wchar_t szSize[50] = _T("");
    swprintf_s(szSize, _T("%d"), strlen(data));
    wstring headers = _T("Content-Length:");
    headers += szSize;
    headers += _T("\r\nContent-Type: application/x-www-form-urlencoded\r\n");
    CString head(headers.c_str());

    //加入首部行,上面这种格式写的首部行,用这个参数HTTP_ADDREQ_FLAG_COALESCE
    BOOL res;
    res = HttpAddRequestHeaders(hRequest, head, head.GetLength(), HTTP_ADDREQ_FLAG_COALESCE);
    if (!res)
    {
        InternetCloseHandle(hInternet);
        InternetCloseHandle(hConnect);
        InternetCloseHandle(hRequest);
        return 0;
    }

   //发送请求 ,最后两个是账号密码的字符数据和长度
    res = HttpSendRequest(hRequest, NULL, 0, data, strlen(data));
    if (!res)
    {
        InternetCloseHandle(hInternet);
        InternetCloseHandle(hConnect);
        InternetCloseHandle(hRequest);
        return 0;
    }

    TCHAR szBuff[50] = {0};   
    DWORD dwBuffSize = 50*sizeof(szBuff);  
    res = HttpQueryInfo(hRequest, HTTP_QUERY_STATUS_CODE, (LPVOID)szBuff, &dwBuffSize, NULL); //查询状态码

    int result = 0;
    int nStatusCode = _tstoi(szBuff);   
    if (nStatusCode== HTTP_STATUS_OK || nStatusCode == HTTP_STATUS_CREATED)
    {
        result = 1;
        TCHAR hdBuff[300] = {0};   
        DWORD headerBuffSize = 300*sizeof(hdBuff);
        HttpQueryInfo(hRequest, HTTP_QUERY_LOCATION, (LPVOID)hdBuff, &headerBuffSize, NULL); //接受cookie;
        strCookie = hdBuff;
        int pos = strCookie.ReverseFind('/');
        strCookie = strCookie.Right(strCookie.GetLength() - pos - 1);
    }

    InternetCloseHandle(hRequest);  
    InternetCloseHandle(hConnect);  
    InternetCloseHandle(hInternet);

    return result;

       获取cookie后,设置cookie

       好像只能用InternetSetCookie(url, null, "xxname=strCookie;path=/;domain=.xxx.com");

      关键是experies, 这个参数设置有效时间,如果时间比当前时间还早,这个cookie就失效了

展开阅读全文

没有更多推荐了,返回首页