小程序encryptedData数据解密报错误码-41003 ? 神奇的问题!!!!!!
mini胖发表于:2022-04-07 14:51:55浏览:1705次
小程序encryptedData数据解密报错误码-41003 ?
希望我的说明能给大家解惑,本文参考了官方的文档以及借鉴了其他小伙伴的经验(参考链接)
联系QQ:1219481875(备注理由)
小程序-41003造成的主要原因在于wx.login方法在wx.getUserProfile方法之后了。到时session_key会话id顺序混乱
以下是全部的实现代码(下载链接)
小程序代码块
wx.login调用
我这里是将wx.login放在app.js中的。大家按自己的实际情况来。code发送到服务端返回的session_key存入缓存,等待wx.getUserProfile后与iv和encryptedData一起发给服务端解密。获取用户信息。
有小伙伴说wx.getUserProfile后前端就能拿到用户信息了,直接明文传送不就好了,省的解密。其实这样很容易被一些有心人注入数据。所以大家还是要注意下数据安全哦!!!!
// app.js
App({
onLaunch() {
// 展示本地存储能力
const logs = wx.getStorageSync('logs') || []
logs.unshift(Date.now())
wx.setStorageSync('logs', logs)
// 登录
wx.login({
success: res => {
// 发送 res.code 到后台换取 openId, sessionKey, unionId
// console.log(res.code)
wx.request({
url: 'http://wxlogin.cn/login.php', //仅为示例,并非真实的接口地址
method:'POST',
data: {act:'login',code:res.code},
header: {
'content-type': 'application/x-www-form-urlencoded' // 默认值
},
success (res) {
wx.setStorage({
key:"login_value",
data:res
})
}
})
}
})
},
globalData: {
userInfo: null
}
})
小程序界面点击
<!--index.wxml-->
<view class="container">
<view class="userinfo">
<block wx:if="{{canIUseOpenData}}">
<view class="userinfo-avatar" bindtap="bindViewTap">
<open-data type="userAvatarUrl"></open-data>
</view>
<open-data type="userNickName"></open-data>
</block>
<block wx:elif="{{!hasUserInfo}}">
<button wx:if="{{canIUseGetUserProfile}}" bindtap="getUserProfile"> 获取头像昵称 </button>
<!-- <button wx:elif="{{canIUse}}" open-type="getUserInfo" bindgetuserinfo="getUserInfo"> 获取头像昵称 </button> -->
<view wx:else> 请使用1.4.4及以上版本基础库 </view>
</block>
<block wx:else>
<image bindtap="bindViewTap" class="userinfo-avatar" src="{{userInfo.avatarUrl}}" mode="cover"></image>
<text class="userinfo-nickname">{{userInfo.nickName}}</text>
</block>
</view>
<view class="usermotto">
<text class="user-motto">{{motto}}</text>
</view>
</view>
触发wx.getUserProfile
// index.js
// 获取应用实例
const app = getApp()
Page({
data: {
motto: 'Hello World',
userInfo: {},
hasUserInfo: false,
canIUse: wx.canIUse('button.open-type.getUserInfo'),
canIUseGetUserProfile: false,
//canIUseOpenData: wx.canIUse('open-data.type.userAvatarUrl') && wx.canIUse('open-data.type.userNickName') // 如需尝试获取用户信息可改为false
canIUseOpenData:false
},
// 事件处理函数
bindViewTap() {
wx.navigateTo({
url: '../logs/logs'
})
},
onLoad() {
if (wx.getUserProfile) {
this.setData({
canIUseGetUserProfile: true
})
}
},
getUserProfile(e) {
// 推荐使用wx.getUserProfile获取用户信息,开发者每次通过该接口获取用户个人信息均需用户确认,开发者妥善保管用户快速填写的头像昵称,避免重复弹窗
wx.getUserProfile({
desc: '展示用户信息', // 声明获取用户个人信息后的用途,后续会展示在弹窗中,请谨慎填写
success: (res1) => {
wx.getStorage({
key: 'login_value',
success (res) {
let login_value=res.data.data;
console.log(login_value);
wx.request({
url: 'http://wxlogin.cn/login.php', //仅为示例,并非真实的接口地址
method:'POST',
data: {act:'login_auth',session_key:login_value.session_key,openid:login_value.openid,encryptedData:res1.encryptedData,iv:res1.iv},
header: {
'content-type': 'application/x-www-form-urlencoded' // 默认值
},
success (res) {
console.log(res);
}
})
}
})
}
})
},
getUserInfo(e) {
// 不推荐使用getUserInfo获取用户信息,预计自2021年4月13日起,getUserInfo将不再弹出弹窗,并直接返回匿名的用户个人信息
console.log(e)
this.setData({
userInfo: e.detail.userInfo,
hasUserInfo: true
})
}
})
php服务端代码块
<?php
$appid="XXX";
$appsecret="XXX";
$act=$_POST['act'];
if($act=='login'){
$code=$_POST['code'];
if(empty($code)){
die('code不存在');
}
$url="https://api.weixin.qq.com/sns/jscode2session?appid=$appid&secret=$appsecret&js_code=$code&grant_type=authorization_code";
$data=http_curl($url);
exit(json_encode($data));
}
if($act=='login_auth'){
// echo $_POST['session_key'];
include_once "./wx/wxBizDataCrypt.php";
$pc = new WXBizDataCrypt($appid, $_POST['session_key']);
$errCode = $pc->decryptData($_POST['encryptedData'],$_POST['iv'], $data );
if ($errCode == 0) {
print($data . "\n");
} else {
print($errCode . "\n");
}
}
function http_curl($url,$type='get',$res='json',$arr=''){
//初始化 curl
$ch = curl_init();
//设置curl的参数
curl_setopt($ch,CURLOPT_URL,$url);
curl_setopt($ch,CURLOPT_RETURNTRANSFER,1);
//处理证书问题
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
//处理结束
if($type == 'post'){
//type 为post
curl_setopt($ch,CURLOPT_POST,1);
curl_setopt($ch,CURLOPT_POSTFIELDS,$arr);
}
//采集
$output = curl_exec($ch);
//关闭
if(curl_errno($ch)){
return curl_errno($ch); //报错
}else{
curl_close($ch);
return json_decode($output,true); //ok
}
}