简介
- 目前该接口针对非个人开发者,且完成了认证的小程序开放(不包含海外主体)。
- 获取微信用户绑定的手机号,需先调用wx.login接口。因为需要用户主动触发才能发起获取手机号接口,所以该功能不由 API 来调用,需用 button 组件的点击来触发。
- 需要将 button 组件 open-type 的值设置为 getPhoneNumber,当用户点击并同意之后,可以通过 bindgetphonenumber 事件回调获取到微信服务器返回的加密数据, 然后在第三方服务端结合 session_key 以及 app_id 进行解密获取手机号。
- 在回调中调用 wx.login 登录,可能会刷新登录态。此时服务器使用 code 换取的 sessionKey 不是加密时使用的 sessionKey,导致解密失败。建议开发者提前进行 login;或者在回调中先使用 checkSession 进行登录态检查,避免 login 刷新登录态。
- 小程序通过设置button组件open-type属性为"getUserInfo"调起授权。
- 小程序使用wx.getUserInfo(Object object),在用户授权后获取用户基本信息。
获取手机号流程
(1)提供button按钮进行授权操作,设置open-type属性为getPhoneNumber,设置bindgetPhoneNumber绑定事件。
<button type='primary' open-type="getPhoneNumber" bindgetphonenumber="getPhoneNumber">授权登录</button>
(2)编写授权绑定事件函数,先调用wx.login登录,然后调用第三方服务接口获取解析后的手机号。
//获取应用实例
const app = getApp()
Page({
data: {
},
//通过绑定手机号登录
getPhoneNumber: function (e) {
var ivObj = e.detail.iv //加密算法的初始向量
var telObj = e.detail.encryptedData //包括敏感数据在内的完整用户信息的加密数据
var codeObj = "";
var that = this;
//执行Login
wx.login({
success: res => {
//console.log('code转换', res.code);
//用code传给服务器调换session_key
wx.request({
url: 'https://www.demo.com/demo/getphone.php', //接口请求地址
data: {
appid: " ", //小程序appid,登录微信后台查看
secret: " ", //小程序secret,登录微信后台可查看
code: res.code,
encryptedData: telObj,
iv: ivObj
},
header: {
'content-type': 'application/json' // 默认值
},
//成功返回数据
success: function (res) {
let phoneObj = res.data.phoneNumber;
//console.log("手机号=", phoneObj)
//存储数据并准备发送给下一页使用
wx.setStorage({
key: "phoneObj",
data: res.data.phoneNumber,
})
}
})
}
})
}
})
(3)服务端构建,引用官方解密文件。
getphone.php
<?php
<?php
//引入官方解密文件
include_once "wxBizDataCrypt.php";
//获取小程序参数
$appid =$_REQUEST['appid'];
$secret =$_REQUEST['secret'];
$js_code=$_REQUEST['code'];
$iv = ($_REQUEST['iv']);
$encryptedData=($_REQUEST['encryptedData']);
$grant_type='authorization_code';
//请求官方API
$objSession= http_curl("https://api.weixin.qq.com/sns/jscode2session?appid=$appid&secret=$secret&js_code=$js_code&grant_type=$grant_type");
//获取session_key和openid
$session_key = json_decode($objSession)->session_key;
$openid = json_decode($objSession)->openid;
$decodeData = new WXBizDataCrypt($appid, $session_key);
$errCode = $decodeData->decryptData($encryptedData, $iv, $data );
if ($errCode == 0) {
print($data. "\n");
} else {
print($errCode . "\n");
}
//模拟https
function http_curl($url){
$curl = curl_init();
//设置抓取的url
curl_setopt($curl,CURLOPT_URL,$url);
curl_setopt($curl,CURLOPT_CONNECTTIMEOUT,30);
//设置获取的信息以文件流的形式返回,而不是直接输出。
curl_setopt($curl,CURLOPT_RETURNTRANSFER,1);
// https请求 不验证证书和hosts
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, FALSE);
//执行命令
$response=curl_exec($curl);
//关闭URL请求
curl_close($curl);
//返回数据
return $response;
}
?>
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);
$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==';
$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");
}
获取用户信息流程
参考:
https://developers.weixin.qq.com/miniprogram/dev/framework/open-ability/getPhoneNumber.html
https://developers.weixin.qq.com/miniprogram/dev/api/open-api/user-info/wx.getUserInfo.html