微信小程序授權(quán)登錄41003錯(cuò)誤
最近遇到這么個(gè)坑,偶然請(qǐng)求己方服務(wù)器授權(quán)登錄失敗,百度上一堆復(fù)制黏貼的文章并不靠譜,最終在微信論壇上看到解決規(guī)劃。
網(wǎng)上有些是說(shuō)iv內(nèi)空格導(dǎo)致解密失敗,我出錯(cuò)的情況下并沒(méi)有出現(xiàn)空格,排除這種情況。
有說(shuō)是因?yàn)檎?qǐng)求順序,但是按照微信官方文檔,似乎并不是最新的,至少我授權(quán)方式不完全跟文檔一樣。
我的授權(quán)方式
通過(guò)添加一個(gè)按鈕并且設(shè)置 open-type="getUserInfo"
- <button class='wxBtn'
- open-type="getUserInfo"
- bindgetuserinfo="wechatAction">操作微信賬號(hào)登錄</button>
在按鈕點(diǎn)擊事件里,會(huì)返回一些授權(quán)登錄需要用到的字段如:iv、encryptedData、signature、rawData 這個(gè)時(shí)候再調(diào)用 wx.login() 去獲取code,整合以上數(shù)據(jù)向己方服務(wù)器發(fā)送請(qǐng)求獲取用戶(hù)唯一標(biāo)識(shí) token。 通過(guò)以上的方式是可以成功登錄,但是偶然會(huì)出現(xiàn)請(qǐng)求己方服務(wù)器授權(quán)登錄失敗,再一次就會(huì)成功。 原因在于請(qǐng)求順序,這里的請(qǐng)求順序是先請(qǐng)求 wx.getUserInfo(按鈕) 再請(qǐng)求 wx.login()。有時(shí)候獲取code后iv已經(jīng)失效,所以失敗。 解決規(guī)劃:在請(qǐng)求 wx.login() 后,調(diào)用一次 wx.getUserInfo(廢棄接口) ,更新iv等信息。注意:這里調(diào)用的廢棄接口只是不再?gòu)棾鍪跈?quán)請(qǐng)求窗口,但還是能夠獲取到 iv 等信息,授權(quán)接口彈窗已將在點(diǎn)擊按鈕的時(shí)候彈出,并且授權(quán)了,所以沒(méi)毛病。 再總結(jié)一下,正確的順序:wx.getUserInfo(按鈕) -> wx.login() -> wx.getUserInfo(廢棄接口),整合以上操作獲取到的最近數(shù)據(jù) code、iv、encryptedData、signature、rawData 傳給己方服務(wù)器,授權(quán)登錄成功。
以下貼上我的業(yè)務(wù)代碼
- // 點(diǎn)擊微信登錄
- wechatAction: function(e) {
- // 用戶(hù)點(diǎn)擊授權(quán)
- // 先保存獲取到的微信用戶(hù)信息
- const { nickName, avatarUrl } = JSON.parse(e.detail.rawData)
- this.setData({
- nickName: nickName,
- avatarUrl: avatarUrl
- })
- // 獲取微信code
- this.reqWechatCode()
- },
- // 微信登錄:獲取code
- reqWechatCode: function() {
- // 授權(quán)接口登錄接口
- let that = this
- // 從微信獲取code
- wx.showLoading({
- title: '獲取code',
- })
- wx.login({
- success: function (res) {
- if (res.code) {
- wx.getUserInfo({
- success: function (res) {
- // 保存微信登錄參數(shù)
- const { encryptedData, iv, signature, rawData } = res
- that.setData({
- encryptedData: encryptedData,
- iv: iv,
- signature: signature,
- rawData: rawData
- })
- that.wxLoginReq(res.code)
- }
- })
- } else {
- wx.showToast({
- title: '獲取code失敗,請(qǐng)重試',
- icon: 'none'
- })
- }
- wx.hideLoading()
- }
- })
- },
- // 根據(jù)獲取到的code 向服務(wù)器發(fā)送登錄請(qǐng)求 獲取token
- wxLoginReq: function (code) {
- let that = this
- wx.showLoading({
- title: '獲取token中',
- })
- // 拿到code 再加上 encryptedData, iv, rawData, signature 等參數(shù),請(qǐng)求token
- let encryptedData = that.data.encryptedData
- let iv = that.data.iv
- let signature = that.data.signature
- let rawData = that.data.rawData
- var req = require('../../util/Request.js')
- // 請(qǐng)求成功
- let success = function(res) {
- // console.log(res)
- wx.hideLoading()
- // 緩存token
- const { token, user_id } = res.data.data
- let userInfo = {
- token: token,
- user_id: user_id,
- nickName: that.data.nickName,
- avatarUrl: that.data.avatarUrl
- }
- getApp().setUserInfo(userInfo)
- // 同步用戶(hù)信息
- getApp().loginSuccess(function () {
- wx.navigateBack({})
- })
- }
- // 請(qǐng)求失敗
- let fail = function(res) {
- wx.hideLoading()
- wx.showToast({
- title: '獲取token失敗,請(qǐng)重試',
- icon: 'none'
- })
- }
- // 登錄請(qǐng)求
- req.reqLogin(code, encryptedData, iv, rawData, signature, success, fail)
- },
第二部分:如何開(kāi)通一個(gè)小商店