微信网页版登陆原理_wxsid-程序员宅基地

技术标签: 前端  html  javascript  

微信网页版登陆原理

  1. 请求微信服务器返回一个会话ID

    微信Web版本不使用用户名和密码登录,而是采用二维码登录,所以服务器需要首先分配一个唯一的会话ID,用来标识当前的一次登录,通过请求地址:

    https://login.weixin.qq.com/jslogin?appid=wx782c26e4c19acffb&redirect_uri=https%3A%2F%2Fwx.qq.com%2Fcgi-bin%2Fmmwebwx-bin%2Fwebwxnewloginpage&fun=new&lang=zh_CN&_=1377482012272(其中1377482012272这个值是当前距离林威治标准时间的毫秒)

服务器会返回如下的字符串:

window.QRLogin.code = 200; window.QRLogin.uuid = "AdrEiQJo7Q==";

而这个AdrEiQJo7Q==字符串就是微信服务器返回给我们的ID。
  1. 通过会话ID获得二维码

    利用刚才获得的ID去请求服务器生成的二维码,通过上面的ID我们组合得到以下的URL地址:
    https://login.weixin.qq.com/qrcode/AdrEiQJo7Q==
    该请求返回的便是我们需要的二维码,此时需要用户在微信的手机版本中扫描这个二维码即可登陆(长按识别二维码都不行,必须是扫描)

  2. 轮询手机端是否已经扫描二维码并确认在Web端登录
    当获得二维码之后,就需要用户去手机端去扫描二维码,并获得用户的授权,此时我们并不知道用户何时完成这个操作,所以我们只有轮询,而轮询的地址就是:
    https://login.weixin.qq.com/cgi-bin/mmwebwx-bin/login?uuid=DeA6idundY9VKn&tip=1&_=1377482045264(注意UUID和最后时间这两个参数)

  • 如果服务器返回:
    window.code=201; window.userAvatar = ''
    则说明此时用户在手机端已经完成扫描,但还没有点击确认;
  • 如果服务器返回:
    window.code=408;
    则说明此时用户在手机端�还未扫描;
  • 如果服务器返回:
    window.code=201;window.redirect_uri=一个URL地址
    则说明此时用户已经在手机端完成了授权过程,保存下这个URL地址下一步 骤中使用.
  1. 访问登录地址,获得uin和sid
    通过访问上一步骤中获得的URL地址,
    https://wx.qq.com/cgi-bin/mmwebwx-bin/webwxnewloginpage?ticket=AVGnnO4cQDp0D-oRRdFpPdKk@qrticket_0&uuid=Qa5hIYJlPg==&lang=zh_CN&scan=1487128220
    可以在服务器返回的Cookies中获得到wxuin和wxsid这两个值,

<?xml version="1.0" encoding="utf-8"?>
<error>
<ret>0</ret>
<message/>
<skey>@crypt_6c791e4d_d2cc04dcc3df812824b41abd98616a44</skey>
<wxsid>BqaMHRqFxeQvdOWD</wxsid>
<wxuin>31213e21</wxuin>
<pass_ticket>fVJ6%2FwoyREZ%2BDIeadCjR%2Fz%2BvAh4keU3A3AvI29NzSaXOdBcxxekwJ51O9S05Q6MG</pass_ticket>
<isgrayscale>1</isgrayscale>
</error>

这两值在后续的通信过程中都要使用到这两个值,并且Cookies中也需要包括这两项。

  1. 初使化微信信息

前面的步骤算是完成了这个复杂的登录过程,如果我们需要使用微信就需要获得当前用户的信息、好友列表等,还有一个关键的就是同步信息(后续与服务器轮询中需要使用同步信息),通过访问以下的链接:
https://wx.qq.com/cgi-bin/mmwebwx-bin/webwxinit?r=1377482058764(r依然是时间)
访问该链接需要使用POST,并且在Body中带上以下的JSON信息:

{"BaseRequest":
{"Uin":"2545437902","Sid":"QfLp+Z+FePzvOFoG","Skey":"","DeviceID":"e1615250492"}}

这个JSON串中Uin和Sid分别是上面步骤中获得的那两个Cookie值,DeviceID是一个本地生成的随机字符串(分析了官方的总是e+一串数字,所以我们也保持这样的格式)。
服务器就会返回一个很长的JSON串,这其中包括:BaseResponse中的值用来表示请求状态码,ContactList主要用来表示联系人(此列表不全,只包括了类似通讯录助手、文件助手、微信团队和一些公众帐号等,后面会通过另一接口去获得更全面的信息),SyncKey是用户与服务器同步的信息,User就是当前登录用户自己的信息。

6.获得所有的好友列表

在上一步骤中已经获得了部分好友和公众帐号,如果需要获得完整的好友信息,就需要访问以下的链接:

https://wx.qq.com/cgi-bin/mmwebwx-bin/webwxgetcontact?r=1377482079876(r依然是时间)

访问该链接同样需要POST方式,但Body为空JSON:{},服务器对身份的判定是通过Cookies,所以需要保持之前访问的Cookies不被修改(在Objective-C中会自动保存相关的Cookies,无需程序特殊处理),在返回的JSON串中,MemberList中就包含了所有的好友信息。

7.保持与服务器的信息同步

与服务器保持同步需要在客户端做轮询,该轮询的URL如下:

https://webpush.weixin.qq.com/cgi-bin/mmwebwx-bin/synccheck?callback=jQuery18309326978388708085_1377482079946&r=1377482079876& sid=QfLp+Z+FePzvOFoG&uin=2545437902&deviceid=e1615250492&synckey=(见以下说明)&_=1377482079876

其中的参数r和_都是time,sid,uin,deviceid与上面步骤的值相对应,此处的synkey是上步步骤获得的同步键值,但需要按一定的规则组合成以下的字符串:

1_124125|2_452346345|3_65476547|1000_5643635

就是将键和值用_隔开,不同的键值对用|隔开,但记得|需要URL编码成%7C,通过访问上面的地址,会返回如下的字符串:

window.synccheck={retcode:”0”,selector:”0”}

如果retcode中的值不为0,则说明与服务器的通信有问题了,但具体问题我就无法预测了,selector中的值表示客户端需要作出的处理,目前已经知道当为6的时候表示有消息来了,就需要去访问另一个接口获得新的消息。

8.获得别人发来的消息

当一个步骤中知道有新消息时,就需要去获取消息内容,通过访问以下的链接:

https://wx.qq.com/cgi-bin/mmwebwx-bin/webwxsync?sid=QfLp+Z+FePzvOFoG&r=1377482079876

上面链接中的参数sid对应上面步骤中的值,r为时间,访问链接需要使用POST方式,Body中包括JSON串,该JSON串格式如下:

{"BaseRequest" : {"Uin":2545437902,"Sid":"QfLp+Z+FePzvOFoG"},
"SyncKey" : {"Count":4,"List":[{"Key":1,"Val":620310295},{"Key":2,"Val":620310303},{"Key":3,"Val":620310285},{"Key":1000,"Val":1377479086}]},
"rr" :1377482079876};

以下的信息中BaseRequest中包括的Uin与Sid与上面步骤中的值对应,SyncKey也是上面步骤中获得的同步键值对,rr为时间,访问成功之后服务器会返回一个JSON串,其中AddMsgList中是一个数组,包含了所有新消息。

9.向用户发送消息

用户主动发送消息,通过以下的URL地址:
https://wx.qq.com/cgi-bin/mmwebwx-bin/webwxsendmsg?sid=QfLp+Z+FePzvOFoG&r=1377482079876
上面的sid和r参数不再解释了,访问该URL采用POST方式,在Body中的JSON串形如以下的格式:

{
"BaseRequest":{
"DeviceID" : "e441551176",
"Sid" : "S8wNi91Zry3024eg",
"Skey" : "F820928BBA5D8ECA23448F076D2E8A915E1349E9FB4F4332",
"Uin" : "2545437902"
},
"Msg" : {
"ClientMsgId" : 1377504862158,
"Content" : "hello",
"FromUserName" : "wxid_2rrz8g8ezuox22",
"LocalID" : 1377504862158,
"ToUserName" : "wxid_j4nu420ojhsr21",
"Type" : 1
},
"rr" = 1377504864463
}

其中BaseRequest都是授权相关的值,与上面的步骤中的值对应,Msg是对消息的描述,包括了发送人与接收人,消息内容,消息的类型(1为文本),ClientMsgId和LocalID由本地生成。rr可用当前的时间。
在返回JSON结果中BaseResponse描述了发送情况,Ret为0表示发送成功。


推荐一个平时工作中非常好用的、简约的ToDoList 待办事项

将工作归还给工作,将生活归还给生活!

ZTodoList ZToDoList今日待办

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/ZToDoList/article/details/122894672

智能推荐

3分钟手把手Studio One 6.6.1中文破解版2024最新图文安装激活教程_studioone中文版-程序员宅基地

文章浏览阅读4.8k次,点赞22次,收藏29次。Studio One6.6.1是一款非常实用的数字音乐创作软件,专门用于创作现代化音乐,软件具有简洁的界面和强大的功能,能够很好地辅助用户创作音乐。顾名思义就是“一个工作室”的意思,它所倡导的制作理念是直接在一个制作软件里完成音乐制作的全部,包括前期的制作缩混和后期的母带处理,所以该软件有两种工作模式,一种是“Song”歌曲前期制作模式,另一种则是“Project”后期母带处理。想想这也很好啊,一个制作平台搞定一切工作,省去在不同软件间的转来转去。_studioone中文版

【附源码】JAVA计算机毕业设计小区物业管理系统(源码+mysql+文档)-程序员宅基地

文章浏览阅读375次,点赞8次,收藏3次。随着城市化进程的快速推进,居住小区成为城市居民生活的主要环境。信息技术的发展为物业管理带来了革新,通过引入先进的管理系统,可以极大地提高管理效率,优化服务质量,实现资源的合理分配和使用。因此,开发一个更为高效、智能的小区物业管理系统0b380,以适应新时代背景下的管理需求,成为了一个亟待解决的问题。智能化的物业管理系统还有助于提升小区的整体形象和品质,吸引更多的住户,增加物业的市场竞争力。随着智慧城市建设的推进,小区物业管理系统0b380的开发将为未来智慧社区的建设打下坚实的基础,促进社会的和谐与进步。

5种五种回归模型及其优缺点_为什么岭回归很少有人用-程序员宅基地

文章浏览阅读3.4w次,点赞7次,收藏60次。参考资料:https://mp.weixin.qq.com/s/mr83EK24S94b_UUlecyqlA 线性回归对异常值非常敏感 多项式拟合如果指数选择不当,容易过拟合。 岭回归标准线性或多项式回归在特征变量之间存在很高的共线性(high collinearity,比如变量x1与x2之间存在函数关系)的情况下将失败。共线性是自变量之间存在近似线性关系,你所..._为什么岭回归很少有人用

Java实现Excel导入和导出,看这一篇就够了(珍藏版)_java导出excel-程序员宅基地

文章浏览阅读10w+次,点赞1k次,收藏5.2k次。前言最近抽了两天时间,把Java实现表格的相关操作进行了封装,本次封装是基于POI的二次开发,最终使用只需要调用一个工具类中的方法,就能满足业务中绝大部门的导入和导出需求。环境准备1. Maven 依赖本次工具类的封装主要依赖于阿里巴巴的JSON包,以及表格处理的POI包,所以我们需要导入这两个库的依赖包,另外,我们还需要文件上传的相关包,毕竟我们在浏览器页面,做Excel导入时,是上传的Excel文件。<!-- 文件上传 --><dependency> _java导出excel

python中scale的用法_在netCDF4和Python中使用scale_factor和add_offset的示例?-程序员宅基地

文章浏览阅读1.5k次。如果您想知道如何使用add_offset和scale_factor参数来打包或解包.nc文件中的数据,可以读取here。使用python(download NCEP reanalysis I data for example)读取netCDF4文件时,可以引用以下代码:>>> import netCDF4 as nc>>> file_obj = nc.Datas..._nc文件 scale_factor

【时序分割】2017KDD论文 Toeplitz Inverse Covariance-Based Clustering of Multivariate Time Series(TICC)_时序数据分割怎么做-程序员宅基地

文章浏览阅读3.7k次,点赞4次,收藏27次。基于Toeplitz逆协方差的多元时间序列数据聚类Toeplitz Inverse Covariance-Based Clustering of Multivariate Time Series Data文章网址:https://www.researchgate.net/publication/318916788_Toeplitz_Inverse_C..._时序数据分割怎么做

随便推点

ANSA二次开发 - Visual Studio Code上搭建ANSA二次开发环境_meta 二次开发-程序员宅基地

文章浏览阅读1.2k次。文章目录Integrating with Microsoft Visual Studio CodeIntroductionANSA and META autocompletionInstallation InstructionsSetting up in Microsoft Visual Studio CodeIntegrating with Microsoft Visual Studio CodeIntroductionVisual Studio Code is a source code edit_meta 二次开发

探索游戏开发新边界:Godot Steering AI Framework-程序员宅基地

文章浏览阅读524次,点赞13次,收藏18次。探索游戏开发新边界:Godot Steering AI Framework项目地址:https://gitcode.com/GDQuest/godot-steering-ai-framework如果你是一名游戏开发者,尤其是热衷于使用开源游戏引擎Godot,那么这款名为Godot Steering AI Framework的项目可能正是你需要的工具。它是一个为Godot设计的智能行为框架,能...

python利用pandas获取每行数据的最大值,最小值以及对应的columns_pandas 输出csv中最大值的序号-程序员宅基地

文章浏览阅读3.6w次,点赞16次,收藏78次。1.先读取文件df = pd.read_csv(path)文件部分内容如下:2.找的每一行的最小值,以及对应的列索引,并在后面增加两列df['max_idx'] = df.idxmax(axis=1) #求一行的最大值对应的索引df['max_val']= df.max(axis=1) #取出该最大值3.找的每一行的最小值,以及对应的列索引,并在后面增加两列(这里需要注意的是,..._pandas 输出csv中最大值的序号

求最大子段和-程序员宅基地

文章浏览阅读289次,点赞8次,收藏7次。【代码】求最大子段和。

【Debug】cv2.imdecode报错“cv2.error: OpenCV(4.6.0) :-1: error: (-5:Bad argument) in function ‘imdecode‘”-程序员宅基地

文章浏览阅读1.7k次。cv2.imdecode报错“cv2.error: OpenCV(4.6.0) :-1: error: (-5:Bad argument) in function 'imdecode'”一招解决。_cv2.error: opencv(4.6.0) :-1: error: (-5:bad argument) in function 'imwrite

常用开发工具IDEA、Sublime Text、chrome等快捷键 Mac版-程序员宅基地

文章浏览阅读224次。2019独角兽企业重金招聘Python工程师标准>>> ..._sublime text 和 idea