WebBrowser多进程共享Cookie的问题。 [问题点数:100分]

love514425
关注
love514425
love514425
等级:Blank
结帖率:97.27%
楼主 发表于: 2014-02-20 09:33:59
WebBrowser如何跨进程共享cookie呢?比如,X.exe里面有一个WebBrowser控件 。执行 X.exe ,此时有就有一个进程A ,然后用WebBrowser访问淘宝,并且登陆淘宝。在 进程A 不关闭的情况下 ,我再 执行 X.exe ,此时有就有一个 进程B ,然后用B进程的WebBrowser访问淘宝,此时需要B进程内的淘宝是已经登录的状态了,就是让B进程能共享A进程的cookie。求高手指教,分不够再加。
回复次数:24
xuddk727
关注
xuddk727 版主
许文君
等级:Blank
2
#1 得分:0 回复于: 2014-02-20 09:40:32
没做过这种,看看以下这篇文章是否有用
http://blog.csdn.net/fhjzgsy/article/details/5157945
love514425
关注
love514425
love514425
等级:Blank
#2 得分:0 回复于: 2014-02-20 10:44:08
引用 1 楼 xuddk727 的回复:
没做过这种,看看以下这篇文章是否有用
http://blog.csdn.net/fhjzgsy/article/details/5157945
这个不是我需要的了,不过还是感谢版主。
love514425
关注
love514425
love514425
等级:Blank
#3 得分:0 回复于: 2014-02-21 09:17:16
没人知道吗? 求大神指教。
对我有用[0] 丢个板砖[0] 引用 | 举报 | 管理
hpygzhx520
关注
hpygzhx520
hpygzhx520
等级:Blank
#4 得分:0 回复于: 2014-03-06 10:34:51
大致原理是HOOK InternetGetCookieEx等,获得INTERNET_COOKIE_HTTPONLY这种cookie,发送到另外一个进程,用InternetSetCookieExW设置。但我也没实验成功……
对我有用[0] 丢个板砖[0] 引用 | 举报 | 管理
hpygzhx520
关注
hpygzhx520
hpygzhx520
等级:Blank
#5 得分:0 回复于: 2014-03-06 13:45:56
说错了,是HOOK WINNET相关函数,用InternetGetCookieEx获取cookie
对我有用[0] 丢个板砖[0] 引用 | 举报 | 管理
xuddk727
关注
xuddk727 版主
许文君
等级:Blank
2
#6 得分:0 回复于: 2014-03-06 15:24:50
给你帖子加亮了,期待有做过相关功能的帮你解答。
对我有用[0] 丢个板砖[0] 引用 | 举报 | 管理
CharlesSimonyi
关注
CharlesSimonyi
CharlesSimonyi
等级:Blank
#7 得分:0 回复于: 2014-03-06 21:59:03
在A进程的WebBrowser中登录淘宝,然后在B进程的WebBrowser中打开淘宝首页,发现并没有登录。
为什么呢?因为保存着登录状态的Cookie是会话级Cookie,不是持久化Cookie。
会话级Cookie与持久化Cookie的不同之处在于:
前者存在内存中,后者存在硬盘文件上。
前者只在当前进程中有效,后者在所有进程中有效。
前者没有规定有效时间,它在进程生命周期内有效,后者规定了明确的有效时间。

那么,我们要做的就是把会话级Cookie变成持久化Cookie,这样在B进程的WebBrowser中打开淘宝首页,这个保存着登录状态的Cookie由于已经被我们转变成了持久化Cookie,在B进程中也有效,会被WebBrowser自动发往淘宝WEB服务器,自然,淘宝服务器也会返回已经登录的状态。

但是这样做的话,是不太安全的,因为这样做以后,即便是浏览器关闭甚至重启电脑,换别人使用这台电脑时,别人打开淘宝首页,也是已经登录的状态。如果不用考虑这种安全问题的话,还是可以这样做的。

把会话级Cookie变成持久化Cookie怎么变?
答案就是使用Wininet提供的API:
InternetGetCookie
InternetSetCookie
InternetGetCookieEx
InternetSetCookieEx

在A进程中登录淘宝后,把和登录状态相关的Cookie甚至直接把全部Cookie用InternetGetCookie取出来,然后用InternetSetCookie设置为持久化的Cookie。
具体方法可以参考这篇文章:
http://blog.csdn.net/charlessimonyi/article/details/17413295

使用的时候要细心细心再细心,除了细心之外,还要再细心,不然总是会得到莫名其妙的无效结果。
这是我折腾了好几天得出的结论,差一点就觉得这几个API无效而放弃了。
一定要结合浏览器HTTP抓包工具一点一点分析,仔细观看HTTP相应头里的Set-Cookie:
另外结合Chrome或Firefox浏览器仔细查看它的每一个Cookie
注意每一个Cookie的PATH、DOMAIN、expires属性,一定要设置对,不然是无效的。

我已经实验过在一些简单的网站上是有效的,确实可以将会话级Cookie变成持久化Cookie而达到你想要的那种效果。那些网站都很简单,用户登录后才有两三个Cookie,其中只有一个保存着登录状态的Cookie,只需对这个Cookie进行这种操作就能实现目的。

但是。
要注意的是,淘宝网的Cookie相当多,相当复杂,有的Cookie还会随着对它页面的访问、随着时间的变化而变化。并且还有一些问题,比如:用IE打开淘宝并登陆,然后便不进行操作了,也不关闭IE页面,长时间过去以后,再点击淘宝上连接,发现登陆状态还是已经退出了。淘宝服务器发现一个客户的Cookie长时间没有再访问页面,也会令该Cookie失效。等等。
不过只要花大量时间仔细分析淘宝的每一个Cookie,慢慢调试、测试你的程序,还是能实现你的目的的。
对我有用[0] 丢个板砖[0] 引用 | 举报 | 管理
CharlesSimonyi
关注
CharlesSimonyi
CharlesSimonyi
等级:Blank
#8 得分:0 回复于: 2014-03-06 22:04:48
还有一个方法是如四楼所说,把A进程中的会话级Cookie用InternetGetCookie取出后发到B进程,用InternetSetCookie设置为B进程中的会话级Cookie。
虽然和“把会话级Cookie设置为持久化Cookie”大同小异,但是更安全,更易于控制Cookie的有效性。
对我有用[0] 丢个板砖[0] 引用 | 举报 | 管理
CharlesSimonyi
关注
CharlesSimonyi
CharlesSimonyi
等级:Blank
#9 得分:0 回复于: 2014-03-06 22:07:53
和HOOK API没关系。
只是要非常细心,要仔细研究分析每一个Cookie,最好看一下Cookie的相关资料比如《HTTP权威指南》之类,对Cookie有个透彻的了解,注意每一个细节,稍有不对就会无效。
对我有用[0] 丢个板砖[0] 引用 | 举报 | 管理
hpygzhx520
关注
hpygzhx520
hpygzhx520
等级:Blank
#10 得分:0 回复于: 2014-03-07 09:20:35
其实说白了,难点在于什么时机获取cookie,又在什么时机设置cookie,以及InternetSetCookieExW设置的时候url参数不全等问题。期待7楼能详细描述下。
对我有用[0] 丢个板砖[0] 引用 | 举报 | 管理
CharlesSimonyi
关注
CharlesSimonyi
CharlesSimonyi
等级:Blank
#11 得分:0 回复于: 2014-03-07 13:06:39
引用 10 楼 hpygzhx520 的回复:
其实说白了,难点在于什么时机获取cookie,又在什么时机设置cookie,以及InternetSetCookieExW设置的时候url参数不全等问题。期待7楼能详细描述下。

是。
InternetGetCookie InternetSetCookie这些API调用很简单,但是要想得到预期的结果,很难。像淘宝这样的网站太复杂了,需要花大量时间精力慢慢分析每一个Cookie是什么时候设置的,每一个Cookie是属于哪个URL,每一个Cookie的变化,每一个Cookie和什么相关。
所以,最好先在那些只有一两个Cookie的简单网站上研究、测试,甚至自行搭建web服务器,自己写web程序代码来研究、测试。
对我有用[0] 丢个板砖[0] 引用 | 举报 | 管理
CharlesSimonyi
关注
CharlesSimonyi
CharlesSimonyi
等级:Blank
#12 得分:0 回复于: 2014-03-07 13:07:43
然后再慢慢的研究复杂一点的网站
对我有用[0] 丢个板砖[0] 引用 | 举报 | 管理
love514425
关注
love514425
love514425
等级:Blank
#13 得分:0 回复于: 2014-04-26 16:52:27
谢谢 @CharlesSimonyi  的热心帮助,不过你说的InternetGetCookie 和 InternetGetCookieEx 获取httponly的cookie的时候是有问题的。好像还是得通过HOOK的方式来处理。
对我有用[0] 丢个板砖[0] 引用 | 举报 | 管理
CharlesSimonyi
关注
CharlesSimonyi
CharlesSimonyi
等级:Blank
#14 得分:0 回复于: 2014-04-26 17:42:02
 InternetGetCookieEx 带Ex后缀的可以获取httponly的cookie,这点MSDN已经说明了,并且需要INTERNET_COOKIE_HTTPONLY标志,要求IE浏览器版本为IE8或以后。
对我有用[0] 丢个板砖[0] 引用 | 举报 | 管理
CharlesSimonyi
关注
CharlesSimonyi
CharlesSimonyi
等级:Blank
#15 得分:0 回复于: 2014-04-26 17:42:23
对我有用[0] 丢个板砖[0] 引用 | 举报 | 管理
love514425
关注
love514425
love514425
等级:Blank
#16 得分:0 回复于: 2014-04-28 09:34:20
引用 14 楼 CharlesSimonyi 的回复:
 InternetGetCookieEx 带Ex后缀的可以获取httponly的cookie,这点MSDN已经说明了,并且需要INTERNET_COOKIE_HTTPONLY标志,要求IE浏览器版本为IE8或以后。
嗯,但是现在项目的需求是不仅要支持IE8,还要支持IE6,IE7。
对我有用[0] 丢个板砖[0] 引用 | 举报 | 管理
CharlesSimonyi
关注
CharlesSimonyi
CharlesSimonyi
等级:Blank
#17 得分:0 回复于: 2014-06-02 18:58:25
WebBrowser的内部是通过Wininet来访问网络的,可以在A进程中Hook Wininet的相关API函数,获取每个有Set-Cookie: 的HTTP响应头,把Cookie取出来,发给B进程进行InternetSetCookieEx设置
对我有用[0] 丢个板砖[0] 引用 | 举报 | 管理
my3439955
关注
my3439955
要追问请引用回复
等级:Blank
#18 得分:0 回复于: 2014-06-03 10:16:06
5-6年前做过从一台机器提取Cookie到另一台机器上免登陆进邮箱的事,是可行的
对我有用[0] 丢个板砖[0] 引用 | 举报 | 管理
stevenkoh
关注
stevenkoh
stevenkoh
等级:Blank
#19 得分:0 回复于: 2014-06-09 21:55:51
死了这条心吧。我试过N多方案了。个人开发的WebBrowser控件无法和IE共享Cookie
对我有用[0] 丢个板砖[0] 引用 | 举报 | 管理
hpygzhx520
关注
hpygzhx520
hpygzhx520
等级:Blank
#20 得分:0 回复于: 2014-07-02 22:39:13
引用 17 楼 CharlesSimonyi 的回复:
WebBrowser的内部是通过Wininet来访问网络的,可以在A进程中Hook Wininet的相关API函数,获取每个有Set-Cookie: 的HTTP响应头,把Cookie取出来,发给B进程进行InternetSetCookieEx设置


这个思路应该是很正确的,关键看细节了,比如到底是HOOK哪个API

对我有用[0] 丢个板砖[0] 引用 | 举报 | 管理
CharlesSimonyi
关注
CharlesSimonyi
CharlesSimonyi
等级:Blank
#21 得分:0 回复于: 2014-07-03 17:56:24
引用 20 楼 hpygzhx520 的回复:
Quote: 引用 17 楼 CharlesSimonyi 的回复:
WebBrowser的内部是通过Wininet来访问网络的,可以在A进程中Hook Wininet的相关API函数,获取每个有Set-Cookie: 的HTTP响应头,把Cookie取出来,发给B进程进行InternetSetCookieEx设置


这个思路应该是很正确的,关键看细节了,比如到底是HOOK哪个API


我Hook的是HttpQueryInfoW
因为WebBrowser的内部每发起一个HTTP请求,都要调用HttpQueryInfoW获取响应头的相关信息。
Hook该API能拦截到每一个HTTP请求。
此方式确实能实现Cookie跨进程共享,并且已经有两个程序员使用此方法开发出了基于WebBrowser的多进程浏览器。
但是后来还有很多复杂的问题,比如共享的Cookie数据应该放在哪里才能给所有进程都能访问并更新,放在DLL共享节还是共享内存?比如其中一个进程获取到一个新Cookie后,如何同步到所有的进程?所有进程都得调用多次InternetSetCookieEx,效率将会很低。等等,越到后面,问题越来越复杂。想要基于WebBrowser做一个高效的多进程浏览器确实很难。毕竟WebBrowser就是个黑箱子,我们只能通过它非常有限的接口来进行二次开发,如果它没有提供某些我们需要的接口,那么就举步维艰了。不知道各种商业化的基于IE的浏览器是如何解决这些技术难题的。
后来我觉得与其使用API Hook这种“旁门左道”来实现WebBrowser没有提供的接口,不如选择一个开源的浏览器内核(如Webkit)来进行二次开发,会好很多。
对我有用[0] 丢个板砖[0] 引用 | 举报 | 管理
hpygzhx520
关注
hpygzhx520
hpygzhx520
等级:Blank
#22 得分:0 回复于: 2014-07-21 09:46:09
得到信息后可以发送到UI进程吧,然后,UI主进程负责转发。但的确很多啊,效率可能的确是问题。但我好奇的还是你实现的细节,我尝试了不成功
对我有用[0] 丢个板砖[0] 引用 | 举报 | 管理
CharlesSimonyi
关注
CharlesSimonyi
CharlesSimonyi
等级:Blank
#23 得分:0 回复于: 2014-07-23 18:17:35
引用 22 楼 hpygzhx520 的回复:
得到信息后可以发送到UI进程吧,然后,UI主进程负责转发。但的确很多啊,效率可能的确是问题。但我好奇的还是你实现的细节,我尝试了不成功