如何在本地開發環境調試微信 JS-SDK

如下篇幅將會描述不一樣前提下對應的調試策略,固然也有可能不是最優解,望斧正 →_→chrome


前言

何謂「安全域名限制」?後端

以微信 JS-SDK 的使用爲例,每一個公衆號被限制最多可設置三個安全域名,且必須能被騰訊服務器所驗證(這意味着域名必須綁定在一臺可被外網訪問的服務器上);而後只容許在這幾個域名下才能使用 JS-SDK,這就是安全域名限制。api

這種策略應用還相對比較普遍,大概能夠等同於三方提供的 API 須要讓你配置 IP 白名單。瀏覽器

下圖大體描述了 JS-SDK 域名驗證的過程,其中緩存

  • WeixinWebview 爲微信客戶端內的瀏覽器;
  • BuServer 爲咱們本身的業務服務器;
  • WeixinClient 爲微信 App;

如下流程的前提是 BuServer 已經具備簽名所需的 access_token、jsapi_ticket 等信息安全

創建在這個基礎上,咱們想繞過這個安全策略,大概有兩種方案:服務器

  1. 常規操做,將一個固定的域名做爲測試專用,填入安全域名列表裏,佔掉一個坑「這邊固然能夠專門申請個測試帳號」,而後經過解決內網穿透「ngrok、花生殼之流」即可以實現;
  2. 很是規操做,經過修改 DNS 解析實現,將特定資源「或全部資源」的請求重寫到本地開發服務上;

常規操做

  1. 經過 ngrok / 花生殼內網穿透,通常工具都會給你臨時域名,固定的域名須要付費;
  2. 將域名填入微信安全域名列表中,並將驗證文件放入 Web 容器裏進行驗證;
  3. 完成了上面兩步,你就能夠愉快的調試啦;

很是規操做

從上文流程圖中能夠看到 JS-SDK config 信息是經過當前請求頁面的 URL + jsapi_ticket + appid + ...... 按照必定規則進行簽名獲得的,而後將這個 config 傳入微信客戶端進行校驗是否合法。微信

整個驗證過程當中,咱們能 hack 的是將請求的資源轉發到開發服務器上,從而能調試本地的代碼。cookie

圍繞「將請求的資源轉發到開發服務器」,能夠想到下面兩個方案:微信開發

  1. 將請求攔截,轉發到開發服務器上;
  2. 利用 DNS 解析,將安全域名解析到開發服務器上「俗稱 DNS 劫持」;

方案一 抓包工具轉發

本文不過多贅述,能夠經過 Charles,Fiddler 這些抓包工具對指定的請求進行轉發,從而達到目的。

方案二 DNS 劫持

能夠先看下圖 DNS 解析過程:

要實現 DNS 劫持,最現實的是經過修改開發機的 hosts 文件將安全域名解析到本地開發環境 ip 上。

HTTP 請求的劫持

若是你的網站提供的是 HTTP 服務,只須要修改開發機中 hosts 文件,將安全域名指向開發服務。看到這裏就差很少了,能夠本身去實踐了。

HTTPs 請求的劫持

可是目前大多數商業網站都 HTTPs 化了,所以並不能簡單的經過 DNS 劫持,把請求轉發到本地的 HTTP 服務上。

若是你的安全域名是一個 HTTPs 服務,那可能有點麻煩。首先咱們來看看一次像 HTTPs Server 請求的時間線:

如上圖能夠看到當像 HTTPs Server 發起一個 HTTP 請求時,將會被永久重定向成 HTTPs 請求,而後響應頭中會有一個特殊的頭「strict-transport-security」,這個頭是告知瀏覽器該域下的全部請求都將使用 HTTPs 訪問。所以接下來若是再發起一個 HTTP 的請求,瀏覽器將會內部重定向至 HTTPs 請求。

上文對 HTTPs 請求的描述是爲了引出當你安全域名對應的是 HTTPs 服務時,會遇到以下問題:

  1. 將安全域名 DNS 劫持到本地 HTTP 服務後,在瀏覽器中訪問仍舊是 HTTPs 請求;
  2. 基於 1 ,咱們想到清瀏覽器緩存,可是微信開發者工具沒法進入 chrome://net-internals/#hsts 清理;

Q1:以 Chrome 爲例,進入 chrome://net-internals/#hsts,清除安全策略。

Q2:在微信開發者工具中,咱們並不能進入這個頁面,也就意味着若是安全域名在該工具中有安全策略緩存,則你沒法將它劫持到一個 HTTP 服務,「這邊若是有什麼方案,能夠告訴我」。

爲了解決這個問題,咱們只能引入終極解決方案,經過一個 HTTPs Server 對請求作一個轉發,具體流程以下:

ProxyServer 作了兩件事:

  • 配置了安全域名對應的 SSL 證書,支持了 HTTPs 請求;
  • 將安全域名下的請求轉發到對應開發服務上;

若是這個 ProxyServer 是做爲一個通用服務存在,則須要考慮如何代理到不一樣開發者啓動的開發服務上。

最開始咱們計劃經過 querystring 來制定須要代理到的開發服務的地址,實際狀況是一個頁面中全部依賴該域下的請求都得轉發,所以 querystring 的方法不能很方便的實現這個功能。

所以最後經過 cookie 來實現這個需求,經過 cookie 指定開發服務器地址,這樣該域下的全部資源請求都會帶上該 cookie,就能實現自定義轉發到上游服務了。

最終使用該方案調試微信 JS-SDK 須要作以下兩步:

  1. 更改 hosts 文件,將安全域名劫持到代理服務上;
  2. 設置 cookie ,指定須要代理到的上游服務;

這樣一來,該代理服務就能夠做爲通用服務所存在,任何開發者有繞過安全域名限制作一些調試,均可以使用這個服務。

FAQ

Q1. 常規操做的優劣?

Pros:

  1. 步驟比較少,容易搞,適合偶爾須要調試;

Cons:

  1. 固定域名要錢💰啊,不固定域名又要常常改,可是一個月又只有三次修改機會啊;
  2. 微信安全域名池子沒坑怎麼辦啊。。。「申請個測試帳號也不是不行,可是這樣後端 access_token、jsapi_ticket 相關接口都得修改」;
  3. 不夠通用,其餘三方登陸有安全域名設置,並不能複用;

針對 Cons 1 有更優解,能夠結合 DNS 劫持,在微信後臺綁定安全域名時使用花生殼驗證域名,而後其實不須要再使用花生殼了,能夠修改 hosts,將驗證的域名劫持到本地開發服務,這樣既不用操心 HTTPs 也不用付費要固定域名。有興趣的小夥伴能夠嘗試嘗試。

Q2. 很是規操做又有什麼優點?

Pros:

  1. 不須要額外的域名,意味着不用改安全域名配置,服務端代碼也不用動;
  2. 通用,有相似安全域名策略的三方服務通殺;
  3. 對於普通開發者來講平常開發調試成本很低,也不須要什麼特殊權限;

Cons:

  1. 搭建流程相對複雜點,須要服務器資源;

Q3. 真機微信裏怎麼調試啊?

祭出 Charles,Mac 用 Charles,Win 用 fiddler 開代理,若是是 HTTPs 則還須要配置證書信任,這個步驟本文再也不贅述,可自行 Google。

Q4. 怎麼申請測試帳號?

mp.weixin.qq.com/debug/cgi-b…

小結

解決方案上,常規方案的額外成本較低,可是在多個開發者協同開發公衆號的狀況下,綜合成本較高;很是規方案比較適合多個開發者須要調試微信 JS-SDK,一勞永逸。

在整個過程當中,其實能夠了解到 DNS 劫持的概念、實際應用,以及對 HTTPs 的進一步瞭解。

最後,若是喜歡能夠關注公衆號「茶杯蓋」

相關文章
相關標籤/搜索