场景描述:
在微信小程序中,我们可能用到很多种登陆方式,例如用手机作为标识登陆亦或者用微信信息作为标识登陆(但这写都要看你的项目需要),在这里我说一下如何使用微信信息作为标识登陆。
编程思路:
分三步走,第一步微信信息获取发送给后台-》第二步解密微信信息验证数据库-》登陆成功保存缓存并且更新token
小程序前端处理
//调用登录接口,获取 code
wx.login({
success: function (res) {
//微信js_code
that.setData({ wxcode: res.code });
//获取用户信息
wx.getUserInfo({
success: function (res) {
//获取用户敏感数据密文和偏移向量
that.setData({ encryptedData: res.encryptedData })
that.setData({ iv: res.iv })
}
})
}
})
为了让大家看得更清楚,我在这里直接打印到视图层(),数据获取到了,接下来将数据发送到后台,有时候后台解密用户信息失败,可能是因为你获取小程序的用户信息再获取用户的code导致的,所以先获取code码再获取用户加密信息
//获取post数组,thinkphp5封装好的input函数,而tp3是I()函数;如果前端使用的是json类型的数据,tp3I函数是获取不了的,只能使用输入流的形式 file_get_contents('php://input');
//这里缺少对数据的验证,大家不要学我,tp5是有验证层
//tp5,获取json和formdata类型
$data = input('post.');
//获取微信信息的基本url,其中%s是转换符,这条url应该存到全局文件中,怎么传自己想
$baseInfoUrl = "https://api.weixin.qq.com/sns/jscode2session?appid=%s&secret=%s&js_code=%s&grant_type=authorization_code";
$infoUrl = sprintf($baseInfoUrl, '填写你的微信小程序appid','填写你的小程序secret_key',$data['code');
$apiData = json_decode(httpCurl($apiUrl), true); //这个是异步调用api,方法在底部
//获取微信用户session_key
(!isset($apiData['session_key'])) ?
throw new Exception('获取微信信息失败')
$errCode = $this->decryptData('你的aooppid', $apiData['session_key'], $data['encryptedData'], $data['iv'], $data); //方法在文章底部
//判断解密是否出错
($errCode != 0) ?
throw new Exception('解密微信信息失败')
$data = json_decode($data, true);//通过引用改变了data信息,解密后获取用户unionId和session_key前者辨别公众号信息,后者获取手机信息(个人认为)
//到这一步就获取到用户的所有信息了$data
//判断用户是否存在,不存在就新增,存在就更新用户信息
//更新用户信息Token和其他基本信息
附带异步调用api和解密微信信息
/**
* 检验数据的真实性,并且获取解密后的明文.
* @param $encryptedData string 加密的用户数据
* @param $iv string 与用户数据一同返回的初始向量
* @param $data string 解密后的原文
*
* @return int 成功0,失败返回对应的错误码
*/
public function decryptData($appid, $sessionKey, $encryptedData, $iv, &$data)
{
$OK = 0;
$IllegalAesKey = -41001;//encodingAesKey 非法
$IllegalIv = -41002;
$IllegalBuffer = -41003;//aes 解密失败
$DecodeBase64Error = -41004;//解密后得到的buffer非法
if (strlen($sessionKey) != 24) {
return $IllegalAesKey;
}
$aesKey = base64_decode($sessionKey);
if (strlen($iv) != 24) {
return $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 $IllegalBuffer;
}
if ($dataObj->watermark->appid != $appid) {
return $IllegalBuffer;
}
$data = $result;
return $OK;
}
/**
* curl请求访问
* @param $url string 地址
* @param $data string post数据
* @return mixed string 返回结果
*/
function httpCurl($url,$data = "")
{
$curl = curl_init();
curl_setopt($curl, CURLOPT_URL, $url);
curl_setopt($curl, CURLOPT_REFERER, $url);
curl_setopt($curl, CURLOPT_USERAGENT, "Mozilla/5.0 (Linux; Android 5.0; SM-N9100 Build/LRX21V) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/37.0.0.0 Mobile Safari/537.36 V1_AND_SQ_5.3.1_196_YYB_D QQ/5.3.1.2335 NetType/WIFI");
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false);
if($data != ''){
curl_setopt($curl,CURLOPT_POST,1);
curl_setopt($curl,CURLOPT_POSTFIELDS,$data);
}
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
$result = curl_exec($curl);
return $result;
}