场景描述:
在微信小程序中,我们可能用到很多种登陆方式,例如用手机作为标识登陆亦或者用微信信息作为标识登陆(但这写都要看你的项目需要),在这里我说一下如何使用微信信息作为标识登陆。
编程思路:
分三步走,第一步微信信息获取发送给后台-》第二步解密微信信息验证数据库-》登陆成功保存缓存并且更新token
小程序前端处理
1 //调用登录接口,获取 code 2 wx.login({ 3 success: function (res) { 4 //微信js_code 5 that.setData({ wxcode: res.code }); 6 //获取用户信息 7 wx.getUserInfo({ 8 success: function (res) { 9 //获取用户敏感数据密文和偏移向量 10 that.setData({ encryptedData: res.encryptedData }) 11 that.setData({ iv: res.iv }) 12 } 13 }) 14 } 15 })
为了让大家看得更清楚,我在这里直接打印到视图层(),数据获取到了,接下来将数据发送到后台,有时候后台解密用户信息失败,可能是因为你获取小程序的用户信息再获取用户的code导致的,所以先获取code码再获取用户加密信息
1 //获取post数组,thinkphp5封装好的input函数,而tp3是I()函数;如果前端使用的是json类型的数据,tp3I函数是获取不了的,只能使用输入流的形式 file_get_contents('php://input'); 2 //这里缺少对数据的验证,大家不要学我,tp5是有验证层 3 4 //tp5,获取json和formdata类型 5 $data = input('post.'); 6 7 //获取微信信息的基本url,其中%s是转换符,这条url应该存到全局文件中,怎么传自己想 8 $baseInfoUrl = "https://api.weixin.qq.com/sns/jscode2session?appid=%s&secret=%s&js_code=%s&grant_type=authorization_code"; 9 $infoUrl = sprintf($baseInfoUrl, '填写你的微信小程序appid','填写你的小程序secret_key',$data['code'); 10 11 $apiData = json_decode(httpCurl($apiUrl), true); //这个是异步调用api,方法在底部 12 13 //获取微信用户session_key 14 (!isset($apiData['session_key'])) ? 15 throw new Exception('获取微信信息失败') 16 $errCode = $this->decryptData('你的aooppid', $apiData['session_key'], $data['encryptedData'], $data['iv'], $data); //方法在文章底部 17 18 //判断解密是否出错 19 ($errCode != 0) ? 20 throw new Exception('解密微信信息失败') 21 $data = json_decode($data, true);//通过引用改变了data信息,解密后获取用户unionId和session_key前者辨别公众号信息,后者获取手机信息(个人认为) 22 23 //到这一步就获取到用户的所有信息了$data 24 25 //判断用户是否存在,不存在就新增,存在就更新用户信息 26 27 //更新用户信息Token和其他基本信息
附带异步调用api和解密微信信息
1 /** 2 * 检验数据的真实性,并且获取解密后的明文. 3 * @param $encryptedData string 加密的用户数据 4 * @param $iv string 与用户数据一同返回的初始向量 5 * @param $data string 解密后的原文 6 * 7 * @return int 成功0,失败返回对应的错误码 8 */ 9 public function decryptData($appid, $sessionKey, $encryptedData, $iv, &$data) 10 { 11 $OK = 0; 12 $IllegalAesKey = -41001;//encodingAesKey 非法 13 $IllegalIv = -41002; 14 $IllegalBuffer = -41003;//aes 解密失败 15 $DecodeBase64Error = -41004;//解密后得到的buffer非法 16 17 if (strlen($sessionKey) != 24) { 18 return $IllegalAesKey; 19 } 20 $aesKey = base64_decode($sessionKey); 21 22 23 if (strlen($iv) != 24) { 24 return $IllegalIv; 25 } 26 $aesIV = base64_decode($iv); 27 28 $aesCipher = base64_decode($encryptedData); 29 30 $result = openssl_decrypt($aesCipher, "AES-128-CBC", $aesKey, 1, $aesIV); 31 32 $dataObj = json_decode($result); 33 if ($dataObj == NULL) { 34 return $IllegalBuffer; 35 } 36 if ($dataObj->watermark->appid != $appid) { 37 return $IllegalBuffer; 38 } 39 $data = $result; 40 return $OK; 41 } 42 43 44 /** 45 * curl请求访问 46 * @param $url string 地址 47 * @param $data string post数据 48 * @return mixed string 返回结果 49 */ 50 function httpCurl($url,$data = "") 51 { 52 $curl = curl_init(); 53 curl_setopt($curl, CURLOPT_URL, $url); 54 curl_setopt($curl, CURLOPT_REFERER, $url); 55 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"); 56 curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false); 57 curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false); 58 if($data != ''){ 59 curl_setopt($curl,CURLOPT_POST,1); 60 curl_setopt($curl,CURLOPT_POSTFIELDS,$data); 61 } 62 curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1); 63 $result = curl_exec($curl); 64 return $result; 65 }