设置HttponlyCookie解决mshtml编程无法获取验证码图片流

最近给客户做的项目有一个新需求,客户需要在打开的IE浏览器中做自动登录,登录的页面上有神兽验证码.解决验证码的方案是找第三方平台打码.这样就有一个问题,如何把正确的验证码传给第三方打码平台.

大家都知道,验证码是随机生成的,每次图片的URL访问都会变化,这样传路径给第三方,图片已经不是页面上的那张图了.于是想到了两种思路去解决这个问题:

1.通过截屏的方式把验证码截取出来再传给第三方打码.

2.抓到IE的Cookie与所有特征参数,利用这些参数发起Request模拟刷新验证码.

由于方式1本人才疏学浅,之前没有研究过这方面相关的知识,于是果断放弃,决定采取plan B.

使用方式2时发现一个问题,SessionID设置了httponly,而这个设置让我们无法直接通过接口读取到httponly的Cookie.这就无法伪装成IE浏览器去刷新验证码了.因为没有SessionID呀,服务器不认识我呀.于是再转换思路,决定先设置好IE的Cookie后再打开网站,这样服务器就能认识我了.能认识我就好办了,再去完成模拟刷新验证码的问题.换个思路后开始重新进行:

1.首先通过HttpRequest请求得到网站的所有Cookie,包括Httponly的.

2.调用wininet.dll给IE浏览器设置我们得到的Cookie.附上设置Cookie的核心代码(网上找的,如有侵权请见谅)

private const int INTERNET_COOKIE_HTTPONLY = 0x00002000;
        [DllImport("wininet.dll", CharSet = CharSet.Auto, SetLastError = true)]
        static extern bool InternetGetCookieEx(string pchURL, string pchCookieName, StringBuilder pchCookieData, ref
        System.UInt32 pcchCookieData, int dwFlags, IntPtr lpReserved);

        [DllImport("wininet.dll", CharSet = CharSet.Auto, SetLastError = true)]
        static extern int InternetSetCookieEx(string lpszURL, string lpszCookieName, string lpszCookieData, int dwFlags,
        IntPtr dwReserved);
        private static string GetCookies(string url)
        {
            uint datasize = 256;
            StringBuilder cookieData = new StringBuilder((int)datasize);
            if (!InternetGetCookieEx(url, null, cookieData, ref datasize, 0x2000, IntPtr.Zero))
            {
                if (datasize < 0)
                    return null;
                cookieData = new StringBuilder((int)datasize);
                if (!InternetGetCookieEx(url, null, cookieData, ref datasize, 0x00002000, IntPtr.Zero))
                    return null;
            }
            return cookieData.ToString();
        }
        public static string SetCookieForIE(string url, CookieCollection cookiestring, string path = "/")
        {
            try
            {
                foreach (Cookie c in cookiestring)
                {
                    string name = c.Name;
                    string value = c.Value + ";expires=" + DateTime.Now.AddDays(1).ToString("r");
                    InternetSetCookieEx(url, name, value, INTERNET_COOKIE_HTTPONLY, IntPtr.Zero);
                }
                return GetCookies(url);
            }
            catch (Exception)
            {
                return "false";
                throw;
            }
        }

3.设置好Cookie后启动IE打开网站,这时使用的SessionID就是我们设置的了,然后用HttpRequst请求刷新验证码得到图片流,传给第三方平台打码得到结果,执行登录,问题解决.

我采用的解决思路就是模拟刷新验证码,如果有其他小伙伴看了此文章有不明白之处,欢迎留言,请轻喷.

原文地址:https://www.cnblogs.com/lzyGod/p/6747890.html