uniapp開發h5應用進行微信網頁授權登錄獲取code失敗

最近正在做企業微信內的h5應用,有微信授權登錄這麼個需求。微信授權登錄並不複雜,整個流程就是按照文檔上描述的:在入口頁構造網頁授權鏈接,跳轉到該鏈接,微信會重定向到入口頁並將code拼在url上,前端將code給到後端,後端調用微信提供的服務端api即可完成登錄。

// 構造如下鏈接來獲取code參數 
https://open.weixin.qq.com/connect/oauth2/authorize?appid=CORPID&redirect\_uri=REDIRECT\_URI&response\_type=code&scope=snsapi\_base&state=STATE#wechat\_redirect

下面貼上代碼,供沒做過的同學參考:

onload(params) { 
	// 獲取url上的code 
	let code = params.code 
	if (code) { 
		// code存在,調用接口將code傳遞給後端
	} else { 
		// code 不存在,走微信網頁授權邏輯 
		
		// 當前網頁的url,供微信重定向使用 
		let loc_href = window.location.href; 
		
		// 對當前頁面的url進行微信要求的urlEncode 處理 
		loc_href = encodeURIComponent(loc_href);
		
		// 構造獲取code的鏈接 
		let appId = '';
		
		// 企業微信應用的CorpID 或者 微信公衆號的appid 
		let wxUrl = `https://open.weixin.qq.com/connect/oauth2/authorize?appid=${appId}&redirect\_uri=${loc_href}&response_type=code&scope=snsapi_base&state=STATE#wechat_redirect`;
		
		// 跳轉鏈接獲取code 
		location.href = wxUrl; } }

代碼寫好後,在微信開發者工具進行調試,發現頁面在微信授權鏈接與當前頁面鏈接之間來回跳轉,說明我們的代碼一直在執行onload中的else邏輯,表示我們並沒有拿到code。 因爲之前做過微信網頁授權登錄,確信自己的代碼邏輯是沒有問題的。唯一區別是之前的項目做的是多頁面應用,使用的是自己開源的框架fast-h5plus

我將微信重定向之後的鏈接拷貝了出來,如下所示:

http://www.xxxx.com/index.html?code=xxxxxx/#/pages/weAuth/weAuth

將鏈接貼出來之後,發現微信並沒有出現bug,它把code返給了我們,只是拼的位置有些不同

// 我們需要的
http://www.xxx.com/index.html#/pages/weAuth/weAuth?code=xxxxx

// 微信實際提供的
http://www.xxx.com/index.html?code=xxxx/#/pages/weAuth/weAuth

代碼無法獲取code說明code拼接在路由的#號之前uniapp是無法進行解析的,自然就不能通過onload的回調參數去獲取。

當時去微信社區搜索了一番,社區中提供的解決辦法有兩種:

  • 使用hsitory模式替代hash路由模式
  • 使用其他方法獲取url上的code值

因爲公司沒打算使用history模式,所以只能使用第二種解決辦法,代碼如下

onload(){
	// 獲取url上的code
	let code = this.getQueryVariable('code')
	if (code) {
		// code存在,調用接口將code傳遞給後端
	} else { 
		// code 不存在,走微信網頁授權邏輯 
		
		// 當前網頁的url,供微信重定向使用 
		let loc_href = window.location.href; 
		
		// 對當前頁面的url進行微信要求的urlEncode 處理 
		loc_href = encodeURIComponent(loc_href);
		
		// 構造獲取code的鏈接 
		let appId = '';
		
		// 企業微信應用的CorpID 或者 微信公衆號的appid 
		let wxUrl = `https://open.weixin.qq.com/connect/oauth2/authorize?appid=${appId}&redirect\_uri=${loc_href}&response_type=code&scope=snsapi_base&state=STATE#wechat_redirect`;
		
		// 跳轉鏈接獲取code 
		location.href = wxUrl; } } 
},
// 獲取url參數
getQueryVariable(variable) {
      var query = window.location.search.substring(1);
      var vars = query.split("&");
      for (var i = 0; i < vars.length; i++) {
        var pair = vars[i].split("=");
        if (pair[0] == variable) { return pair[1]; }
      }
      return (false);
}

通過手動解析url獲取code成功的解決了該問題,拿到code,返給後端,登錄成功跳轉首頁,一切正常。

本來文章寫到這裏就該結束了,但在後續開發中,當頁面需要使用微信jsapi時出問題了。

某個頁面需要使用微信jsapi時,流程爲 前端將當前url返給後端,後端將timestamp,nonceStr,signaure返過來。前端調用wx.config方法進行接口注入權限驗證配置

wx.config({
    beta: true,// 必須這麼寫,否則wx.invoke調用形式的jsapi會有問題
    debug: true, // 開啓調試模式,調用的所有api的返回值會在客戶端alert出來,若要查看傳入的參數,可以在pc端打開,參數信息會通過log打出,僅在pc端時纔會打印。
    appId: '', // 必填,企業微信的corpID
    timestamp: , // 必填,生成簽名的時間戳
    nonceStr: '', // 必填,生成簽名的隨機串
    signature: '',// 必填,簽名,見 附錄-JS-SDK使用權限簽名算法
    jsApiList: [] // 必填,需要使用的JS接口列表,凡是要調用的接口都需要傳進來
});

在開發者工具調試時,控制檯一直提示授權失敗,簽名無效。查看了文檔中對簽名生成的描述如下:

簽名生成規則如下: 參與簽名的參數有四個:

  • noncestr(隨機字符串),
  • jsapi_ticket(如何獲取參考“獲取企業jsapi_ticket”以及“獲取應用的jsapi_ticket接口”),
  • timestamp(時間戳),
  • url(當前網頁的URL, 不包含#及其後面部分)

前端只是傳遞了url給後端生成簽名,後端同學也反覆檢查了代碼表示沒有問題。那問題只有可能出在傳遞的這個url上。

微信文檔描述 url 參數爲當前網頁的URL,不包含#及其後面部分。

正常的一個url 
http://www.xxx.com/index.html#pages/index/index?id=xxxx

去掉#號之後的url 
http://www.xxx.com/index.html

但因爲我們在hash模式下,微信授權之後url變成了這樣:
http://www.xxx.com/index.html?code=xxxx#/pages/index/index?id=xxx

去掉#號之後地址
http://www.xxx.com/index.html?code=xxxx

問題極有可能出在這裏。去掉url上的?及後面的所有字符,傳遞給後端,後端重新生成簽名後再執行wx.config,授權成功,問題解決!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章