zoukankan      html  css  js  c++  java
  • php 微信小程序转义403

    function code 微信 iv 偶现 encryptedData 41003 encodeURIComponent

    关于小程序微信授权登录提示41003

    文章简介

    之前做项目的时候遇到微信授权登录偶现的41003问题,也是排查了好久才找到原因,在这边做下记录,也做下分享。

    原因一(iv和encryptedData转码问题)

    因为微信小程序提供的特定授权按钮 button open-type=“getPhoneNumber”,获得的iv和encryptedData,会含有 "+ ?"特殊符号,所以前端这边传输的时候需要使用encodeURIComponent 函数进行 urlencode,后端接收urldecode,
    例如:

    // An highlighted block
    let param = {
    	encryptedData: encodeURIComponent(e.detail.encryptedData),
    	iv: encodeURIComponent(e.detail.iv),
    	code: code
    }

    试了一下全部转码了,结果没啥卵用,还是没有解决 偶现的41003问题,重新排查,排查终于排查到了第二个原因。

    原因二(wx.login()获取code顺序问题)

    本来的的代码是这样,例:

    // An highlighted block
    <button open-type="getPhoneNumber" @getphonenumber="getPhoneNumber">微信一键登录,领取名片</button>
    // An highlighted block
    getPhoneNumber: function(e) {
    	uni.login({
    		success: function(loginRes) {
    			let param = {
    				encryptedData: encodeURIComponent(e.detail.encryptedData),
    				iv: encodeURIComponent(e.detail.iv),
    				code: loginRes.code
    			}
    			wx.request({
    				data: param,
    				success:function() {
    				
    			})
    		}
    	})	
    }

    经过尝试发现wx.login()里code的获取是不能放在 button* *open-type="getPhoneNumber"的回调函数里面的,code应该是需要提前获取了,例:

    // An highlighted block
    <button open-type="getPhoneNumber" @getphonenumber="getPhoneNumber">微信一键登录,领取名片</button>
    // An highlighted block
    // 每次已进入页面就请求code,存放本地,过了有效期五分钟,重新请求code
    onShow() {
    	wxlogin()
    	// 微信登录code有效期 五分钟
    	this.globalTimer = setInterval(() => {
    		wxlogin()
    	}, 299990)
    }
    
    // 请求code方法
    wxlogin = function() {
    	uni.login({
    		success: function(loginRes) {
    			uni.setStorageSync('code', loginRes.code);	
    		}
    	})
    }
    // *button** ==*open-type="getPhoneNumber"回调
    getPhoneNumber: function(e) {
    	let param = {
    		encryptedData: encodeURIComponent(e.detail.encryptedData),
    		iv: encodeURIComponent(e.detail.iv),
    		code: uni.getStorageSync('code');	
    	}
    	wx.request({
    		data: param,
    		success:function() {
    		
    	})
    }
    // 离开页面 清除定时器
    onHide() {
    	if (this.globalTimer) {
    		clearInterval(this.globalTimer)
    	}
    },


    后端应该修改成这样:
    /**
    * 换取用户信息
    * @param string $code 用户登录凭证(有效期五分钟)
    * @param string $iv 加密算法的初始向量
    * @param string $encryptedData 加密数据( encryptedData )
    * @return array
    * @throws InvalidDecryptException
    * @throws InvalidResponseException
    * @throws WeChatExceptionsLocalCacheException
    */
    public function userInfo($code, $iv, $encryptedData)
    {
    $result = $this->session($code);
    if (empty($result['session_key'])) {
    //code换取session失败 再试一次
    $result = $this->session($code);
    if (empty($result['session_key'])) {
    throw new InvalidResponseException('Code 换取 SessionKey 失败', 403);
    }
    }
    $userinfo = $this->decode($iv, $result['session_key'], $encryptedData);
    if (empty($userinfo)) {
    $iv = urldecode($iv);
    $encryptedData = urldecode($encryptedData);
    $userinfo = $this->decode($iv, $result['session_key'], $encryptedData);
    if (empty($userinfo)) {
    throw new InvalidDecryptException('用户信息解析失败', 403);
    }
    }
    return array_merge($result, $userinfo);
    }
     

    改成这种提前获取code然后再传入getPhoneNumber的回调函数使用仪器传给后端发现 偶现的==41003== 问题就解决了。

    引用 https://www.icode9.com/content-1-896152.html

  • 相关阅读:
    Jupyter-notebook安装问题及解决
    [模块] scrapy_splash(迁移)
    pychram-redis破解
    scrapy-redis(迁移)
    123
    day44作业
    sql 的基本数据类型
    基本数据库操作
    安装数据库与配置使用环境
    线程知识点——Event事件
  • 原文地址:https://www.cnblogs.com/zlf2000/p/14758333.html
Copyright © 2011-2022 走看看