需要将<button>组件open-type的值设置为getPhoneNumber,当用户点击并同意之后,可以通过bindgetphonenumber事件回调获取到微信服务器返回的加密数据,然后在第三方服务端结合session_key以及app_id进行解密获取手机号。
在回调中调用wx.login登录,可能会刷新登录态。此时服务器使用code换取的sessionKey不是加密时使用的sessionKey,导致解密失败。建议开发者提前进行login;或者在回调中先使用checkSession进行登录态检查,避免login刷新登录态。
签名校验以及数据加解密涉及用户的会话密钥session_key。开发者应该事先通过wx.login登录流程获取会话密钥session_key并保存在服务器。为了数据不被篡改,开发者不应该把session_key传到小程序客户端等服务器外的环境。
wx.login调用时,用户的session_key可能会被更新而致使旧session_key失效(刷新机制存在最短周期,如果同一个用户短时间内多次调用wx.login,并非每次调用都导致session_key刷新)。开发者应该在明确需要重新登录时才调用wx.login,及时通过code2Session接口更新服务器存储的session_key。
微信不会把session_key的有效期告知开发者。我们会根据用户使用小程序的行为对session_key进行续期。用户越频繁使用小程序,session_key有效期越长。
开发者在session_key失效时,可以通过重新执行登录流程获取有效的session_key。使用接口wx.checkSession可以校验session_key是否有效,从而避免小程序反复执行登录流程。
<?php
/**
*对微信小程序用户加密数据的解密示例代码.
*
*@copyrightCopyright(c)1998-2014TencentInc.
*/
namespacewechat;
classwxBizDataCrypt
{
private$appid;
private$sessionKey;
/**
*构造函数
*@param$sessionKeystring用户在小程序登录后获取的会话密钥
*@param$appidstring小程序的appid
*/
publicfunction__construct($appid,$sessionKey)
{
$this->sessionKey=$sessionKey;
$this->appid=$appid;
}
/**
*检验数据的真实性,并且获取解密后的明文.
*@param$encryptedDatastring加密的用户数据
*@param$ivstring与用户数据一同返回的初始向量
*@param$datastring解密后的原文
*
*@returnint成功0,失败返回对应的错误码
*/
publicfunctiondecryptData($encryptedData,$iv,&$data)
{
if(strlen($this->sessionKey)!=24){
returnerrorCode::$IllegalAesKey;
}
$aesKey=base64_decode($this->sessionKey);
if(strlen($iv)!=24){
returnerrorCode::$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)
{
returnerrorCode::$IllegalBuffer;
}
if($dataObj->watermark->appid!=$this->appid)
{
returnerrorCode::$IllegalBuffer;
}
$data=$result;
returnerrorCode::$OK;
}
}
/**
*errorcode说明.
*<ul>
*<li>-41001:encodingAesKey非法</li>
*<li>-41003:aes解密失败</li>
*<li>-41004:解密后得到的buffer非法</li>
*<li>-41005:base64加密失败</li>
*<li>-41016:base64解密失败</li>
*</ul>
*/
classerrorCode
{
publicstatic$OK=0;
publicstatic$IllegalAesKey=-41001;
publicstatic$IllegalIv=-41002;
publicstatic$IllegalBuffer=-41003;
publicstatic$DecodeBase64Error=-41004;
}
改造
<?php
/**
*对微信小程序用户加密数据的解密示例代码.
*
*@copyrightCopyright(c)1998-2014TencentInc.
*/
namespacewechat;
classwxBizDataCrypt
{
private$appid;
private$sessionKey;
/**
*errorcode说明.
*<ul>
*<li>-41001:encodingAesKey非法</li>
*<li>-41003:aes解密失败</li>
*<li>-41004:解密后得到的buffer非法</li>
*<li>-41005:base64加密失败</li>
*<li>-41016:base64解密失败</li>
*</ul>
*/
publicstatic$OK=0;
publicstatic$IllegalAesKey=-41001;
publicstatic$IllegalIv=-41002;
publicstatic$IllegalBuffer=-41003;
publicstatic$DecodeBase64Error=-41004;
/**
*构造函数
*@param$sessionKeystring用户在小程序登录后获取的会话密钥
*@param$appidstring小程序的appid
*/
publicfunction__construct($appid,$sessionKey)
{
$this->sessionKey=$sessionKey;
$this->appid=$appid;
}
/**
*检验数据的真实性,并且获取解密后的明文.
*@param$encryptedDatastring加密的用户数据
*@param$ivstring与用户数据一同返回的初始向量
*@param$datastring解密后的原文
*
*@returnint成功0,失败返回对应的错误码
*/
publicfunctiondecryptData($encryptedData,$iv,&$data)
{
if(strlen($this->sessionKey)!=24){
returnself::$IllegalAesKey;
}
$aesKey=base64_decode($this->sessionKey);
if(strlen($iv)!=24){
returnself::$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)
{
returnself::$IllegalBuffer;
}
if($dataObj->watermark->appid!=$this->appid)
{
returnself::$IllegalBuffer;
}
$data=$result;
returnself::$OK;
}
}