1. 前言
特別注意:個(gè)人號(hào)小程序無法使用
目前該接口針對(duì)非個(gè)人開發(fā)者,且完成了認(rèn)證的小程序開放(不包含海外主體)
微信開發(fā)文檔: https://developers.weixin.qq.com/miniprogram/dev/framework/open-ability/getPhoneNumber.html
2. 獲取用戶授權(quán)手機(jī)號(hào) button 組件
定義按鈕組件,用于調(diào)起授權(quán)手機(jī)號(hào)彈窗
<button open-type="getPhoneNumber" bindgetphonenumber="getPhoneNumber">獲取手機(jī)號(hào)</button>
bindgetphonenumber
事件回調(diào)
methods: {
// 獲取用戶授權(quán)的手機(jī)號(hào)
getPhoneNumber: e => {
if (e.detail.errMsg === 'getPhoneNumber:ok') {
wx.request({
url: 'http://tp6.cy/',
method: 'POST',
data: {
iv: e.detail.iv,
encryptedData: e.detail.encryptedData,
},
success: res => {
console.log(res)
}
})
} else {
wx.showToast({
title: '拒絕授權(quán)',
})
}
},
}
將以下數(shù)據(jù)傳給后端,后臺(tái)可通過解密數(shù)據(jù)得到手機(jī)號(hào)
{
"encryptedData": "PIxZLRab9M9EQha6Od5WA5NT...",
"iv": "CVN4qd7zUe6+vz9wuAvReQ=="
}
3. 使用 EasyWechat 4.x 消息解密獲取手機(jī)號(hào)
composer require overtrue/wechat:~4.0
消息解密文檔: https://easywechat.com/docs/4.x/mini-program/decrypt
一、獲取小程序相關(guān)功能所屬實(shí)例
$app = Factory::miniProgram($config);
https://easywechat.com/docs/4.x/mini-program/index
二、進(jìn)行消息解密時(shí)最好使用 try catch
捕獲可能出現(xiàn)的異常
try {
// 消息解密
// $session 根據(jù) wx.login 的臨時(shí)登錄憑證 code 換取的 session_key
// $iv, $encryptedData 在 bindgetphonenumber 事件回調(diào)中獲取
$decryptedData = $app->encryptor->decryptData($session, $iv, $encryptedData);
} catch (\Throwable $th) {
// 解密失敗
// 當(dāng)使用的$session已過期時(shí),解密會(huì)拋出異常,
// 此時(shí)錯(cuò)誤信息:The given payload is invalid.
echo $th->getMessage();
}
// 手機(jī)號(hào)為空代表解密失敗 fault 是自定義的拋出異常的函數(shù)
empty($decryptedData['phoneNumber']) && fault('解密失敗');
// 解密成功后的操作
// ...
三、解密成功 $decryptedData
的值
{
"phoneNumber": "15037846666",
"purePhoneNumber": "15037846666",
"countryCode": "86",
"watermark": {
"timestamp": 1622695392,
"appid": "wxb80ec74221f8a9ff"
}
}
4. 在 EasyWechat 4.x 使用新接口獲取手機(jī)號(hào)
從基礎(chǔ)庫 2.21.2 開始,對(duì)獲取手機(jī)號(hào)的接口進(jìn)行了安全升級(jí),bindgetphonenumber 事件回調(diào)方法中的 e.detail 中增加了一個(gè) code 屬性。新版本接口不再需要提前調(diào)用 wx.login 進(jìn)行登錄(調(diào)用 wx.login 是為了獲取 session_key)
{
"code": "dbad746bbaf51214f081e133668cc5a5ebbb9a526ad9e7b503e337a59c60414c",
"encryptedData": "PIxZLRab9M9EQha6Od5WA5NT...",
"iv": "CVN4qd7zUe6+vz9wuAvReQ=="
}
前端開發(fā)者只需要將上面的 code 傳遞給接口,后端開發(fā)者就能獲取到手機(jī)號(hào),因?yàn)檫@個(gè)接口是新版的,EasyWechat4.x 還沒有更新,所以需要自己手動(dòng)調(diào)用新版接口,代碼示例如下所示
/**
* 獲取用戶授權(quán)手機(jī)號(hào)
* @param string $code
*/
function getPhoneNumber(string $code)
{
$app = Factory::miniProgram($config);
$access_token = $app->access_token->getToken()['access_token'];
$url = 'https://api.weixin.qq.com/wxa/business/getuserphonenumber?access_token=' . $access_token;
// 使用 curl 發(fā)送網(wǎng)絡(luò)請(qǐng)求
$result = https_request($url, json_encode(['code' => $code]));
$array = json_decode($res, true);
if (isset($array['errcode']) && $array['errcode'] == 0) {
// 獲取成功
// 手機(jī)號(hào): $array['phone_info']['phoneNumber']
} else {
// 獲取失敗
}
}
/**
* http請(qǐng)求
* @param string $url 請(qǐng)求的地址
* @param string $data 請(qǐng)求參數(shù)
*/
function https_request($url, $data = null)
{
$curl = curl_init();
curl_setopt($curl, CURLOPT_URL, $url);
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false);
if (!empty($data)) {
curl_setopt($curl, CURLOPT_POST, 1);
curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
}
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
$output = curl_exec($curl);
curl_close($curl);
return $output;
}