Vue:在Vue中實現(xiàn)微信網(wǎng)頁授權和分享

前言

自己開始開發(fā)的時候也在網(wǎng)上搜過些教程,尤以segmentfault和腳本之家的兩篇文章為甚,然后兩篇文章都只是講了自己的場景和如何使用,卻沒有講述其中的原理。我不喜歡只會用的程度,如果不明白為什么這么做,每一步做的理由,所以寫下這篇文章,分享一下我在開發(fā)中的心得。

前期準備

web開發(fā)者工具.png

你肯定不愿意每次都在手機上調(diào)試,因為不能console,所以你得準備這個渣渣開發(fā)者工具,mac下容易假死。有大佬改chrome,偽裝成微信瀏覽器,我沒試過,不知道能不能成功。

natapp.png

然后是natapp,或許大家會有疑問,我都有服務器了,還買這個穿透工具干啥?因為微信簽證和當前瀏覽器URL有關(微信設置JS安全域名),你肯定不想每次打包后都拜托后臺大哥傳上去你再調(diào)試吧。但是本地的localhost 192.168.x.x是無效的,因此通過natapp把當前主機暴露到外網(wǎng),這樣可以臨時設置JS安全域名到這里,就可以進行驗簽和授權了。

額外補充

我們知道,做Vue開發(fā)會通過express開啟一個臨時服務器,我試過natapp直接映射到這個服務器,前端請求會報錯,content-length not match。所以我就用anywhere對打包后的文件又開了一個本地服務器,這樣其實效率挺低的,希望哪位大佬告訴我解決方案。

渣渣mac

該問題存在于mac下,windows下無問題。

網(wǎng)頁授權和分享

這倆貨其實是不一樣的,得分開實現(xiàn),網(wǎng)頁授權是一套機制。分享是另一套機制。我們先看看分享

微信分享

微信分享步驟.png

首先綁定域名,這個就填natapp的臨時域名就好了。然后引入JS文件,npm上有現(xiàn)成的包import wx from 'weixin-js-sdk';,第三個就是最重要的了。debug參數(shù)開啟了,你的驗簽信息,分享結果,成功與失敗都會以alert形式的彈窗彈出來了。調(diào)試的階段我們需要打開,接著幾個參數(shù)都沒太大的問題,唯一難點在于signature。簽名

signature

這些參數(shù)都應該初始化過程中請求后臺,由后臺返回。值得注意的是signature,在附錄中有詳細的介紹。這個signature會和當前瀏覽器的URL有關,并且注冊以后如果URL發(fā)生改變需要重新注冊。什么意思呢?
vue-router中如果mode設置為history模式,如果進入不同路由時,URL發(fā)生了變化,此時微信認為你的URL是不合法的,因此驗簽失效了,你就得必須重新驗簽。
如果每一個路由都重新驗簽對于我這種強迫癥是受不了的。因此我們使用hash模式,這樣路由會響應#號后面的變化,真正的地址沒有發(fā)生變化。因此只需要一處驗簽,后面都不會受到影響。
下面是我的驗簽代碼

驗簽.png

首先發(fā)出一段ajax請求,講當前的URL傳遞給后臺,后臺會根據(jù)這個URL生成signature,注意這里使用的是window.location.href.split('#')[0]方法,不能寫死。因為如果進行網(wǎng)頁授權的話。query參數(shù)會出現(xiàn)在#號前面。比如http://xxx.xx.com/?xx=xx&xx=xx&/#/xxx,這個query參數(shù)將會伴隨整個頁面的生命周期。并且其中的參數(shù)是動態(tài)變化的,如果寫死將會導致驗簽失敗。ajax拿到后臺數(shù)據(jù)后進行驗簽,成功后調(diào)試模式下會有提示。接著進行分享

分享.png

如果出現(xiàn)正確的圖片和title,并且調(diào)試信息無誤的話一個分享就成功了。值得注意的是,分享出去的URL必須和簽名的URL一樣,否則分享會失?。ㄎ以囘^分享授權的鏈接,失敗了)。并且如果當前用戶沒有訂閱的話,分享出去也只是title和一串URL地址,只有訂閱用戶才能分享出圖片和描述。
在頻繁改動appid的時候(測試需要),有的時候微信服務器會有緩存,導致正確的簽名順序也會報錯誤的驗簽,這個時候等等就好了。
目前只做了風險,驗簽和分享坑差不多就這些。

網(wǎng)頁授權

這個其實很簡單,就是誘導一個用戶跳轉(zhuǎn)到一個網(wǎng)頁,這個網(wǎng)頁的URL配置了一些參數(shù),按照相關的要求由后臺配好以后點進去就行了。靜默授權,就是不獲取用戶的信息,表現(xiàn)就是鏈接跳出去又跳回來。獲取信息就是用戶點擊一個確認授權,然后你就可以獲取該用戶的相關信息了。
這個示例鏈接是
https://open.weixin.qq.com/connect/oauth2/authorize?appid=wxf0e81c3bee622d60&redirect_uri=http%3A%2F%2Fnba.bluewebgame.com%2Foauth_response.php&response_type=code&scope=snsapi_userinfo&state=STATE#wechat_redirect
其中的redirect_uri就是回調(diào)的URL,授權成功后,將轉(zhuǎn)入這個頁面,并且攜帶兩個query參數(shù),其中的code就是授權碼,通過這個授權碼獲取該用戶的openid。
這個授權碼有時間限制,并且只能使用一次。將這個授權碼發(fā)送給后臺以后,后臺請求openid,這個openid是唯一的,可以通過這個openid在數(shù)據(jù)庫中綁定用戶。之后的邏輯就和非微信環(huán)境沒有太大區(qū)別了。

業(yè)務邏輯

整個業(yè)務邏輯就是,首先判斷是不是微信環(huán)境(我們的網(wǎng)頁要求移動端同樣能用)

const isWechat = () => {
  let ua = window.navigator.userAgent.toLowerCase();
  return ua.match(/MicroMessenger/i) == 'micromessenger';
}

如果是微信環(huán)境,就對他進行驗簽。此時并未網(wǎng)頁授權,網(wǎng)頁授權和驗簽可以分開。

授權的邏輯放在開啟探索這個按鈕上
首先是判斷當前是否存在code(因為這可能已經(jīng)是授權后的頁面,因此先檢查是否有code,再判斷是否需要跳轉(zhuǎn)授權頁)

const getQuery = name => {
  var reg = new RegExp('(^|&)' + name + '=([^&]*)(&|$)', 'i');
  var r = window.location.search.substr(1).match(reg);
  if (r != null) {
      return unescape(r[2]);
  }
  return null;
} 

如果code存在就把code發(fā)給后臺,根據(jù)后臺的返回結果處理自己的業(yè)務邏輯。code不存在則通過
window.location.href=xxxxx跳轉(zhuǎn)到微信授權頁,授權成功后又跳轉(zhuǎn)到當前頁面,此時code存在。
如果需要其他JSSDK服務,就讓后臺吧通過code獲取的openid,accesstoken保存下來。有些用戶已經(jīng)使用過了網(wǎng)站服務,或者網(wǎng)站需要用戶的手機號,獲取code以后就跳轉(zhuǎn)一個綁定頁,要求用戶綁定手機或者郵箱,這個地方根據(jù)自己的業(yè)務邏輯來。
因為要同時處理微信與非微信登錄,所以這里的判斷邏輯比較復雜,建議先草稿紙規(guī)劃好,考慮到每一個情況再敲代碼。不然到時候甩鍋都甩不好。

結束

微信開發(fā)確實是一個不小的難題,并非代碼多高深,主要難在調(diào)試的環(huán)境上。每一個域名綁定,授權都很復雜。相關的文檔個人覺得也并不完善。并且最坑爹的是微信會緩存appid,這樣在開發(fā)切換到生產(chǎn)環(huán)境的時候,微信服務器得appid并沒有切換成功,導致驗簽失敗。在你確認簽名配置無誤的時候,依舊發(fā)生驗簽失敗,那么你就等等吧。
另外,未驗簽分享出去的title默認就是網(wǎng)頁的title,也就是document.title。
:)就是這樣

最后編輯于
?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容