小程序Yii框架获取手机号前段+后端代码php版报-41003解决方法
先说一下整体环境
后端用的Yii框架
写这块功能时遇到个小坑,记录下来,希望可以帮助到大家
前端代码
<button open-type="getPhoneNumber" bindgetphonenumber="getPhoneNumber"> 获取手机号 </button>
getPhoneNumber: function (e) {
var that=this;
if (e.detail.errMsg == 'getPhoneNumber:fail') {
console.log(ErrMsg);
that.showToast_fail('未获取到手机号码');
return false;
} else if (e.detail.iv == undefined || !e.detail.iv) {
that.showToast_fail('授权失败');
return false;
} else {
// 解密手机号接口
var url = "wx-login/get-phone-num";
var params = {
sessionkey: encodeURI(wx.getStorageSync('session_key')),
encryptedData: encodeURI(e.detail.encryptedData),
iv: encodeURI(e.detail.iv)
};
util.request(url, 'POST', params, '', (res) => {
that.setData({
phone: res.data.phoneNumber,
})
wx.reLaunch({
url: '../index/index',
})
}, function () {
that.showToast_fail('获取手机号失败');
})
}
}
util.js里面方法
const formatTime = date => {
const year = date.getFullYear()
const month = date.getMonth() + 1
const day = date.getDate()
const hour = date.getHours()
const minute = date.getMinutes()
const second = date.getSeconds()
return [year, month, day].map(formatNumber).join('/') + ' ' + [hour, minute, second].map(formatNumber).join(':')
}
const formatNumber = n => {
n = n.toString()
return n[1] ? n : '0' + n
}
// 网络请求
const request = function(url, method, data, msg, succ, fail, com) {
// 小程序顶部显示Loading
wx.showNavigationBarLoading();
if (msg != "") {
wx.showLoading({
title: msg
})
}
wx.request({
url: 'http://tianze.com/index.php/'+url,
data: data,
header: {
'content-type': 'application/x-www-form-urlencoded'
},
// dataType:'json',
method: method,
success: res => {
if (succ) succ(res);
},
fail: err => {
wx.showToast({
title: '网络错误,请稍后再试···',
icon:'none'
})
if (fail) fail(err);
},
complete: com => {
wx.hideNavigationBarLoading();
if (msg != "") {
wx.hideLoading();
}
console.log(url + ' 返回的data:', com.data);
}
})
}
module.exports = {
formatTime: formatTime,
request: request
}
前端代码结束,登录部分代码,自行解决。这里就不写了。获取手机号,就是用session_key还有iv和encryptedData,去服务端解码。大家注意的是,现在想获取手机号,需要用户点击按钮授权,才会调用方法。获取以上参数,后直接调用服务端接口。
服务端代码,自己直接去小程序官网上下载,加密算法代码。
wxBizDataCrypt.php
<?php
namespace common\wxApi;
/**
* 对微信小程序用户加密数据的解密示例代码.
*
* @copyright Copyright (c) 1998-2014 Tencent Inc.
*/
use common\wxApi;
class WXBizDataCrypt
{
private $appid;
private $sessionKey;
/**
* 构造函数
* @param $sessionKey string 用户在小程序登录后获取的会话密钥
* @param $appid string 小程序的appid
*/
public function __construct( $appid, $sessionKey)
{
$this->sessionKey = $sessionKey;
$this->appid = $appid;
}
/**
* 检验数据的真实性,并且获取解密后的明文.
* @param $encryptedData string 加密的用户数据
* @param $iv string 与用户数据一同返回的初始向量
* @param $data string 解密后的原文
*
* @return int 成功0,失败返回对应的错误码
*/
public function decryptData( $encryptedData, $iv, &$data )
{
if (strlen($this->sessionKey) != 24) {
return ErrorCode::$IllegalAesKey;
}
$aesKey=base64_decode($this->sessionKey);
if (strlen($iv) != 24) {
return ErrorCode::$IllegalIv;
}
$aesIV=base64_decode($iv);
$aesCipher=base64_decode($encryptedData);
$result=openssl_decrypt( $aesCipher, "AES-128-CBC", $aesKey, 1, $aesIV);
$dataObj=json_decode( $result );
if( $dataObj == NULL )
{
return ErrorCode::$IllegalBuffer;
}
if( $dataObj->watermark->appid != $this->appid )
{
return ErrorCode::$IllegalBuffer;
}
$data = $result;
return ErrorCode::$OK;
}
}
errorCode.php
<?php
namespace common\wxApi;
/**
* error code 说明.
* <ul>
* <li>-41001: encodingAesKey 非法</li>
* <li>-41003: aes 解密失败</li>
* <li>-41004: 解密后得到的buffer非法</li>
* <li>-41005: base64加密失败</li>
* <li>-41016: base64解密失败</li>
* </ul>
*/
class ErrorCode
{
public static $OK = 0;
public static $IllegalAesKey = -41001;
public static $IllegalIv = -41002;
public static $IllegalBuffer = -41003;
public static $DecodeBase64Error = -41004;
}
?>
调用php方法
接口代码
我这里用的Yii框架
/**获取手机号解密方法*/
public function actionGetPhoneNum(){
$appid = 'wx8d4adb9';
$request = Yii::$app->request;
$sessionKey = $request -> post('sessionkey','');
$encryptedData = $request ->post('encryptedData');
$iv = $request -> post('iv');
$data = '';
$WxBizDataCrypt = new WxBizDataCrypt($appid, $sessionKey);
$errCode = $WxBizDataCrypt->decryptData($encryptedData, $iv, $data );
if ($errCode == 0) {
return ($data . "\n");
} else {
return ($errCode . "\n");
}
}
用Yii框架写,一定要注意,前端写请求Header时候一定要写,‘content-type’: ‘application/x-www-form-urlencoded’
不然Yii post方法获取不到值。
报-41003;解决方法
sessionkey: encodeURI(wx.getStorageSync(‘session_key’)),
encryptedData: encodeURI(e.detail.encryptedData),
iv: encodeURI(e.detail.iv)
参数要加上encodeURI()进行解析
希望可以帮助到大家。