如何开发一个个性化的Web版微信(1)

Web版微信登陆


github地址https://github.com/hty7/vue-w...
若有不足与错误,请见谅vue

Web版微信主要参考Web微信协议进行设计开发
项目主要分红三大模块
登陆模块:微信扫码登陆流程
微信容器:微信信息、会话接收发送、心跳监测
数据存储:用户登陆信息、状态信息、会话信息webpack

*先祭图拜八哥已求无bug*

图片描述

效果图
咱们但愿实现的功能包括基本的登陆、聊天群发功能(文本/表情/图片/文件/公众号连接)、公众号阅读、聊天记录导出保存、用户画像、聊天机器人ios

clipboard.png

前期工做准备

DEMO主要采用web微信接口进行开发,所以在实际开发中必须调用微信接口
问题:
(1)接口跨域问题(本地开发跨域、cookie)
(2)状态检测问题(心跳检测,微信会话活动中必须保持心跳接口的正常联接)
(3)接口前缀问题(微信经常使用有wx及wx2两个版本)
(4)数据存储问题(用户通信录的用户UserName会随着每次登陆而改变,所以必须经过特殊方法处理数据一致性及连贯性)nginx

在前期咱们须要解决(1)(2)两个问题
因为项目里使用vue+axios+webpack本地开发,请求以下git

// 获取微信惟一uid
export const getUUID = params => {
  return axios.get('/login/jslogin', {params: params})
}

开发阶段使用http-proxy-middleware解决跨域问题github

'/login': {
    target: 'https://login.wx.qq.com', // 重定向路径
    secure: false, // htts转http证书验证问题
    changeOrigin: true,
    headers: { // 设置报头
      Referer: 'https://login.wx.qq.com'
    },
    pathRewrite: { // 路径重写
      '^/login': '/'
    }
  }

经过上面代理,能够将本地localhost:8080//login/jslogin => https://login.wx.qq.com/jslogin完成跨域操做
但上面的方面还不能彻底解决跨域问题,在后面的请求咱们能够知道心跳checkasync和通信录头像等请求都须要使用到cookie,所以咱们必须将wx.qq.com域名下返回的cookie保存的本地域名下,所以咱们必须解决跨域cookie的问题web

clipboard.png

所以咱们能够经过配置proxy进行跨域处理,经过cookieDomainRewrite重写domian,咱们能够将不一样域名下的cookie保存到咱们所需域名下。同时因为默认请求是不带cookie,发起请求前须要配置请求中的withCredentials = true,使请求带上cookie.axios

'/wx1': {
    target: 'https://wx.qq.com',
    secure: false,
    changeOrigin: true,
    headers: {
      Referer: 'https://wx.qq.com'
    },
    pathRewrite: {
      '^/wx1': '/'
    },
    onProxyRes: (proxyRes, req, res) => {
      let cookies = proxyRes.headers['set-cookie']
      let cookieRegex = /Secure/i
      //修改cookie secure
      if (cookies) {
        let newCookie = cookies.map((cookie) => {
          if (cookieRegex.test(cookie)) {
            return cookie.replace(cookieRegex, '')
          }
          return cookie
        })
        //修改cookie path
        delete proxyRes.headers['set-cookie']
        proxyRes.headers['set-cookie'] = newCookie
      }
    },
    // 重写cookie domian
    cookieDomainRewrite: {
      '*': 'localhost'
    }
  }

若是须要在生产环境中须要跨域,能够参考网上解答
如nginx环境下能够修改nginx.conf配置跨域

proxy_cookie_domain 'wx.qq.com' $host;

问题(2)中,咱们须要注意web微信接口并不是一成不变,不一样帐号登陆会跳到不同的接口,已知的存在两种可能性
如获取微信登陆用户信息/cgi-bin/mmwebwx-bin/webwxnewloginpage接口,就存在两种前缀
https://wx.qq.com/cgi-bin/mmw...
https://wx2.qq.com/cgi-bin/mm...
所以咱们必须在登陆前从login登陆接口(下面会详细解析)获取该微信重定向的地址微信

登陆模块

获取UUID

clipboard.png

method: GET
path: /login/jslogin
参数:

appid: 'wx782c26e4c19acffb', // appid (固定值)
redirect_uri: 'https://wx.qq.com/cgi-bin/mmwebwx-bin/webwxnewloginpage', // 重定向路径
fun: 'new', // (固定值)
lang: 'zh_CN', // 语言版本 (固定值)
_: new Date().getTime() // 时间戳

响应返回值:window.QRLogin.code = 200; window.QRLogin.uuid = "AZc-ETs6NA==";
返回值为字符串,能够经过正则式获得code和uuid

res = {
    code: 200,
    uuid: 'AZc-ETs6NA=='
}

获取二维码

https://login.weixin.qq.com/q...{uuid}

https://login.weixin.qq.com/qrcode/AZc-ETs6NA==

等待登陆扫码

method: GET
path: /cgi-bin/mmwebwx-bin/login
参数:

loginicon: true,
uuid: uuid,
tip: 0,
r: ~new Date().getTime(),
_: new Date().getTime()

等待登陆扫码是一个长轮询接口(25S左右),用户扫码到肯定存在不一样响应状态
(1)长时间未扫码,登陆超时

window.code=408;

(2)扫码未肯定,获取用户头像

window.code=201;window.userAvatar='data:img/jpg;base64';

(3)扫码未肯定,超出限制时间,二维码无效需从新扫码
window.code=400;
(4)扫码并肯定

window.code=200;
window.redirect_uri="https://wx.qq.com/cgi-bin/mmwebwx-bin/webwxnewloginpage?ticket=Acej3HhQ4Mcb8CrNtZkOooln@qrticket_0&uuid=Ia-L18JF6w==&lang=zh_CN&scan=1535295440";

获取微信登陆令牌(登陆中最重要的一步)

method: GET
path: /cgi-bin/mmwebwx-bin/webwxnewloginpage

上一步扫码成功后redirect_uri后面加上&fun=new&version=v2
例如:https://wx.qq.com/cgi-bin/mmw...

响应:

<error>
<ret>0</ret>
<message></message>
<skey>@crypt_ca4ca197_6abe45393fc8632b547d6231c537a5f5</skey>
<wxsid>gYCDNcRRyujtvMEF</wxsid>
<wxuin>\*\*\*\*\*\*\*\*</wxuin>
<pass_ticket>6huRNbBOP9XzXc4bZiD8H%2BJIRH6spE11Vn86Fgpn6VNfW5%2BJfDcxlQ%2B%2Bt5TSb7Cb</pass_ticket>
<isgrayscale>1</isgrayscale>
</error>

返回值未XML格式,须要把skey, wxsid, wxuin, pass_ticket参数解析出来并保存,后面的请求参数都须要用到

同时咱们也须要保存Response cookie,也就是前面提到的第一个问题

clipboard.png

相关文章
相关标签/搜索