介绍
这里面涉及两个技术
1、涉及getPhoneNumber
接口的使用,用以获取用户的相应信息;
官方文档:https://developers.weixin.qq.com/miniprogram/dev/framework/open-ability/getPhoneNumber.html
2、涉及开放数据的加解密问题
官方文档:https://developers.weixin.qq.com/miniprogram/dev/framework/open-ability/signature.html
注:
要获取用户手机号,需要用户对微信进行手机绑定后才能成功,不然会报获取失败
操作流程:
第一步
登录,获取用户的 session_key;(这个我就不多说了,不懂的可以去看微信登陆 session_key 的获取)第二步
点击按钮调用getPhoneNumber
事件,得到 encryptedData 和 iv 。把encryptedData 和 iv 传到后端进行解密。第三步
在服务端通过session_key,encryptedData 和 iv 进行解密,获得相应用户信息并传递给客户端。
具体示例代码
前端
wxml
<button open-type="getPhoneNumber" bindgetphonenumber="getPhoneNumber">获取手机号</button>
js
Page({
getPhoneNumber (e) {
console.log(e.detail.errMsg)
console.log(e.detail.iv)
console.log(e.detail.encryptedData)
}
})
得到的iv
和 encryptedData
都是一串best64
加密后的字符串。大概是这样子的
iv
iv = 'r7BXXKkLb8qrSNn05n0qiA=='
encryptedData
$encryptedData="CiyLU1Aw2KjvrjMdj8YKliAjtP4gsMZM
QmRzooG2xrDcvSnxIMXFufNstNGTyaGS
9uT5geRa0W4oTOb1WT7fJlAC+oNPdbB+
3hVbJSRgv+4lGOETKUQz6OYStslQ142d
NCuabNPGBzlooOmB231qMM85d2/fV6Ch
evvXvQP8Hkue1poOFtnEtpyxVLW1zAo6
/1Xx1COxFvrc2d7UL/lmHInNlxuacJXw
u0fjpXfz/YqYzBIBzD6WUfTIF9GRHpOn
/Hz7saL8xz+W//FRAUid1OksQaQx4CMs
8LOddcQhULW4ucetDf96JcR3g0gfRK4P
C7E/r7Z6xNrXd2UIeorGj5Ef7b1pJAYB
6Y5anaHqZ9J6nKEBvB4DnNLIVWSgARns
/8wR2SiRS7MNACwTyrGvt9ts8p12PKFd
lqYTopNHR1Vf7XjfhQlVsAJdNiKdYmYV
oKlaRv85IfVunYzO0IKXsyl7JCUjCpoG
20f0a04COwfneQAGGwd5oa+T8yO5hzuy
Db/XcxxmK01EpqOyuxINew==";
示例图
个人代码示例
getPhoneNumber:function(e){
wx.getStorage({
key: 'cache_key',
success (cache) {
// 数据请求
getPhone({cache_key:cache.data,iv:e.detail.iv,encryptedData:e.detail.encryptedData}).then(res=>{
console.log(res);
})
}
})
},
注:这个cache_key
是我对应后端的存储的 session_key
的key。不懂的可以简单理解成为这就是我的session_key
。直接传session_key
去请求也是可以的。从安全角度考虑一般session_key
只是放在服务端的。
getPhone
是我封装的请求函数
后台以PHP
后台官方demo包:点击下载
示范代码
wxBizDataCrypt.php(解码封装类)
<?php
/**
* 对微信小程序用户加密数据的解密示例代码.
*
* @copyright Copyright (c) 1998-2014 Tencent Inc.
*/
include_once "errorCode.php";
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); // 通过sessionKey iv encryptedData; 解码。
$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
/**
* 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;
}
?>
demo.php(示范代码)
<?php
include_once "wxBizDataCrypt.php";
$appid = 'wx4f4bc4dec97d474b';
$sessionKey = 'tiihtNczf5v6AKRyjwEUhQ==';
//请求的时候,三个参数都是best64 加密后的字符串。如果格式不对,就得检查一下数据格式了
$encryptedData="CiyLU1Aw2KjvrjMdj8YKliAjtP4gsMZM
QmRzooG2xrDcvSnxIMXFufNstNGTyaGS
9uT5geRa0W4oTOb1WT7fJlAC+oNPdbB+
3hVbJSRgv+4lGOETKUQz6OYStslQ142d
NCuabNPGBzlooOmB231qMM85d2/fV6Ch
evvXvQP8Hkue1poOFtnEtpyxVLW1zAo6
/1Xx1COxFvrc2d7UL/lmHInNlxuacJXw
u0fjpXfz/YqYzBIBzD6WUfTIF9GRHpOn
/Hz7saL8xz+W//FRAUid1OksQaQx4CMs
8LOddcQhULW4ucetDf96JcR3g0gfRK4P
C7E/r7Z6xNrXd2UIeorGj5Ef7b1pJAYB
6Y5anaHqZ9J6nKEBvB4DnNLIVWSgARns
/8wR2SiRS7MNACwTyrGvt9ts8p12PKFd
lqYTopNHR1Vf7XjfhQlVsAJdNiKdYmYV
oKlaRv85IfVunYzO0IKXsyl7JCUjCpoG
20f0a04COwfneQAGGwd5oa+T8yO5hzuy
Db/XcxxmK01EpqOyuxINew==";
$iv = 'r7BXXKkLb8qrSNn05n0qiA==';
$pc = new WXBizDataCrypt($appid, $sessionKey);
$errCode = $pc->decryptData($encryptedData, $iv, $data );
if ($errCode == 0) {
print($data . "\n");
} else {
print($errCode . "\n");
}
个人代码示例(thinkphp6)
/**
* 解密用户手机号码信息
* @param Request $request
* @return mixed
* @throws \Psr\SimpleCache\InvalidArgumentException
*/
public function getPhone(Request $request){
$data = UtilService::postMore([
['cache_key', ''],
['iv', ''],
['encryptedData', ''],
]);
$session_key = Cache::get('eb_api_code_' . $data['cache_key']); // 通过cache_key获取对应的session_key
$phoneData = MiniProgramService::encryptor($session_key, $data['iv'], $data['encryptedData']);
return app('json')->success($phoneData);
}
请求结果
array:4 [
"phoneNumber" => "18712345678"
"purePhoneNumber" => "18712345678"
"countryCode" => "86"
"watermark" => array:2 [
"timestamp" => 1658137285
"appid" => "wxa4582b8c794a603a"
]
]
示例图