admin管理员组

文章数量:1531714

背景:

   不知道大家没有没接触过微信自动添加好友的软件,还有第三方基于微信做的功能,如分流抢票中的微信通知,可以指定人发消息,还有一些,微信集成机器人的功能.总之我对这一类的软件始终保持着强烈的求知欲和好奇心.终于有一天我忍不住揭开它神秘的面纱,看看她诱人的丝袜下掩盖着着的到底是怎样一双美腿. 终于,终于,我找到了揭开那层面纱的关键词.微信web端通信协议

开始:

 善用搜索的人,可能已经读过一篇解析微信网页版api的文章了,我也是看了那篇文章才想细细的研究一遍,求甚解.

打开微信网页版 你会看到一个二维码,打开控制台,点击netweok你会看到所有请求.

通过分析不难发现,页面优先调取了一个https://login.wx.qq/jslogin 接口 获取uuid,然后使用uuid去获取二维码https://login.weixin.qq/qrcode/IeJfvSS6vw==

最后调取一个接口去监听用户扫描二维码.

那么扫描就分为了三部分

1:获取UUID

2:获取二维码

3:监听用户扫描二维码

部分截图

 

 

一步一步说

获取UUID

代码写的有点糙了,大佬凑合着看吧.

接口详细描述

地址:
url: https://login.wx.qq/jslogin
参数:

appid: wx782c26e4c19acffb // 随便写
fun: new // 固定new
lang: zh_CN // 固定zh_CN
_: 1554721401246 // 当前时间戳

router.get('/', function (req, res, next) {
  let getUUID = function () {
    axios.get('https://login.wx.qq/jslogin', {
      params: {
        appid: global.appId,
        redirect_uri: 'https://wx.qq/cgi-bin/mmwebwx-bin/webwxnewloginpage',
        fun: 'new',
        lang: 'zh_CN',
        _: +new Date()
      }
    }).then(loginRes => {
      console.log(loginRes.data)
      uuid = loginRes.data.split(';')[1].split('= ')[1].replace(/"/g, "")
      global.uuid = uuid
      console.log('UUID为____' + uuid)
      res.render('index', {
        title: 'Express',
        imgData: `https://login.weixin.qq/qrcode/${uuid}`
      });
    })
  }
  getUUID()
});

 

此处注意坑点1:该接口返回结果不是json而是text

需要自己处理转换

 

获取二维码地址

uuid就是上一步的返回值
https://login.weixin.qq/qrcode/${uuid}

监听二维码扫描


// 监听扫描结果方法
async function _queryScanStatus(tip) {
  let url = 'https://wx.qq/cgi-bin/mmwebwx-bin/login'
  let body = {
    tip: tip,
    uuid: global.uuid,
    _: +new Date(),
    loginicon: true
  }
  let res = await axios.get(url, {params: body})
  return dataToJson(res.data)
}

// 监听扫描结果入口
async function getScanResult() {
  let scanRes = await _queryScanStatus(1)
  if (scanRes['window.code'] == 201) {
    let confirmRes = await _queryScanStatus(0)
    if (confirmRes['window.code'] == 200) {
      let data = queryToJson(confirmRes['window.redirect_uri'])
      return data
    }
  }
}

function queryToJson(url) {
  let index = url.indexOf('?')
  let apiURL = url.substr(0, index)
  let query = url.substr(index + 1)
  let data = dataToJson(query, '&')
  data.apiURL = apiURL
  return data
}

// 监听第一阶段
router.get('/listnScan', function (req, res) {
  _queryScanStatus(1).then(scanRes => {
    if (scanRes['window.code'] == 201) {
      res.json({scanRes})
    }
  })
})

// 监听第二阶段
router.get('/listnScanConfirm', function (req, res) {
  _queryScanStatus(0).then(confirmRes => {
    if (confirmRes['window.code'] == 200) {
      let data = queryToJson(confirmRes['window.redirect_uri'])
      res.json({data})
    }
  })
})

此处一开始我很难理解, 或者去监听用户扫描了,困扰了我很久,但当我注意到调取这个接口会,服务一直处于pending状态我就立即明白了,原来用了那么low的处理啊.

注意这里需要二次调取接口,一次是用户扫描,一次是用户点击了确定登录的按钮.

代码如上:

接口详细描述:

接口地址
url: https://login.wx.qq/cgi-bin/mmwebwx-bin/login

请求方式
method: get

参数
loginicon: true // 固定rue
uuid: 4db-Azt7kA== // 第一步获取的uuid
tip: 0 // 固定值 0获取1 0:是否扫描; 1:是否确定登录
r: 56037589 // 
_: 1554722097962 // 当前时间戳

 

代码地址

过程:

整个过程还是挺有意思的,目前代码才刚写到用户点击确定登录的监听, 初始化用户数据还没做. 我会慢慢加上去的,后续还考虑封装api供第三方使用.如果你也想参与请在下方评论留言

高潮:

除了那个监听用户扫描状态的接口比较耗时了一些,还有就是解析返回结果

用户扫描后,会返回用户头像的接口这个接口奇坑无比. 有多种数据格式返回,需要做兼容.具体请看代码

另外需求注意的一点是 生成二维码和去监听扫描决不能同时去请求, 否则会报超时返回408

 

后续:

未完待续......

 

本文标签: 源码通讯网页最新web