如何開發一個個性化的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

相關文章
相關標籤/搜索