最近给客户开发小程序,要用到小程序获取手机号的功能,网上很多教程都能实现,但是真的太繁琐了,个人特别不喜欢各种引用和耦合,没打算跨域复用就简简单单写在控制器里就行了,所以这次也把功能简化了,以尽可能的小白视角可以进行使用。
前端比较简单,就是使用getPhoneNumber按钮的getphonenumber事件进行调用按钮功能这里以uniapp为例,如果是其他,如微信就直接用“wx.”来替换就行。
getphone(e){
let that = this;
if (!e.detail.iv) {uni.showToast({title:'获取手机号失败',icon:'none'});return;}
uni.checkSession({
success(val){
if(val.errMsg == 'checkSession:ok'){
console.log(e.detail)
var obj = {code:that.code,iv:e.detail.iv,encryptedData:e.detail.encryptedData}
that.decryptPhone(obj);
}else{
uni.login({
provider: 'weixin',
success(res) {
let code = res.code;
var obj = {code,iv:e.detail.iv,encryptedData:e.detail.encryptedData}
that.decryptPhone(obj);
}
})
}
}
})
},
decryptPhone(obj){
var that = this;
uni.request({
url:'https://xxx.com/getUserPhone',
data:obj,
method:'POST',
success: res => {
console.log( res.data);
},
fail: res => {
console.log( res);
},
})
},
这里不使用uniapp的自行修改request 和login部分的代码
后端是争议最多的,很多人部署遇到问题主要是这里,有些人连基本的引用都搞不清楚,对于官方下载下来的wxBizDataCrypt.php之类的文件都不知道怎么办,这里以TP5为例,其他语言或框架都可以参照,因为取消了各类文件的引用的和调用,用最简单的方式放到控制器里了,所以真的去用的时候大家可以完全复制粘贴,改下appid和secret就行。
public function getUserPhone() {
$code =input();
$appid = $this->wxconfig['appId'];
$secret = $this->wxconfig['secret'];
$encryptedData = $code['encryptedData'];
$js_code = $code ['code'];
$iv = $code ['iv'];
$url = 'https://api.weixin.qq.com/sns/jscode2session?appid=' . $appid . '&secret=' . $secret . '&js_code=' . $js_code . '&grant_type=authorization_code';
$data = "";
$ch = curl_init();$header=[];
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);curl_setopt($ch, CURLOPT_POST, true);curl_setopt($ch, CURLOPT_HEADER, $header);curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
$rest= curl_exec($ch);
curl_close($ch);
if ($rest) {
$recod = json_decode($rest);
$crr['open_id'] = $recod->openid;
$errCode = $this->decryptData($appid, $recod->session_key,$encryptedData, $iv, $data1); //微信解密函数
if ($errCode == 0) {
$data = json_decode($data1, true);
$phoneNumber = $data['phoneNumber'];
return $phoneNumber;
} else {return '请求失败'.$phoneNumber;}
} else {return '网络请求失败';}
}
public function decryptData($appid,$sessionKey, $encryptedData, $iv, &$data )
{
if (strlen($sessionKey) != 24) {return -41001;}
$aesKey=base64_decode($sessionKey);
if (strlen($iv) != 24) {return -41002;}
$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 -41003;}
if( $dataObj->watermark->appid != $appid){return -41003;}
$data = $result;
return 0;
}
这里只有两个function,curl之类的都没有提出来单写,因为之前有读者复制我的代码的时候说curlHttp重复,我也是苦笑不得。
下面的代码直接复制到控制器中改下appid和secret就可以用了