PHP快速实现微信小程序授权

小程序开发讲究的就是一个敏捷软件开发模式,作为微信小程序授权也有多个项目的积累,所以想贴出来代码,让需要用到的朋友拿来即用(当然前提是需要修改自己的小程序appid和秘钥)。

  1. 前端调用wx.login()获取code值。
  2. 前端通过调用wx.getUserInfo获取iv、rawData、signature、encryptedData等加密数据,传递给服务端。
  3. 服务器通过code请求api--auth.code2Session,换回session_key和openid(判断用户的openid是否在数据库中不在就提交,再给前端发送token(md5用户id+时间戳) )。
  4. 前端发送消息到服务器时带上token,即请求服务端接口时,token作为参数与其他参数一并传来。
  5. 服务器验证token(需要用户数据表创建一个token字段(char 64))。
appid&secret=$this->secret&js_code=$code&grant_type=authorization_code"; //dump($url); $result = $this->getJson($url); if(isset($result['errcode'])){ return \Response::echoError($result['errmsg']); }else{ $session_key = $result['session_key']; $signature = $data['signature']; $raw = trim($data['rawData']); $encryptedData = https://www.it610.com/article/$data['encryptedData']; $iv = $data['iv']; if(empty($signature) || empty($raw) || empty($encryptedData) || empty($iv)){ return \Response::echoError('参数不完整!'); } $signature2 = sha1($raw.$session_key); if($signature != $signature2){ return \Response::echoError('签名错误!'); } $user_info = new wxBizDataCrypt($this->appid, $session_key); $errCode = $user_info->decryptData($encryptedData, $iv, $info); if($errCode != 0){ return \Response::echoError($errCode); } $info = json_decode($info,true); // 检查是否已存在该微信小程序的用户openid,存在表示之前已授权,直接更新token $res = Model('User') ->where([ 'openId' => $info['openId'] ]) ->first(); Model()->startTrans(); if(!$res){ $result_res = Model('User') ->create([ 'nickname' => $info['nickName'], 'openid' => $info['openId'], 'headimgurl' => $info['avatarUrl'], 'gender' => $info['gender'], 'create_time' => date('Y-m-d H:i:s'), 'update_at' => date('Y-m-d H:i:s'), ]); if(!$result_res){ Model()->rollback(); return \Response::echoError('授权失败!'); }else{ //保存当前用户登录信息(用户id等)到缓存 $loginLogic = new LoginLogic(); $loginLogic->save($result_res->id); // 更新token $token = md5($result.time()); Model('User') ->where([ 'id' => $result_res->id ]) ->update([ 'token' => $token ]); Model()->commit(); return \Response::echoSuccess($token, '授权成功!'); } }else{ // 更新token $token = md5($res['id'].time()); Model('User') ->where([ 'id' => $res->id ]) ->update([ 'token' => $token ]); Model()->commit(); return \Response::echoSuccess($token, '已授权成功!'); } } }/** * curl的get请求 * @param $url * @return mixed */ function getJson($url){ $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE); curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); $output = curl_exec($ch); curl_close($ch); return json_decode($output, true); } }

对微信小程序用户加密数据的解密示例代码
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 = https://www.it610.com/article/$result; return ErrorCode::$OK; } } }

保存当前用户登录信息(用户id等)到缓存的LoginLogic.php
class LoginLogic{ /** * 保存登录信息到缓存 * @param $user_id */ function save($user_id){ // 用户信息 $info = Model('User') ->where([ 'id' => $user_id ]) ->first([ 'id', 'openid', ]); if(empty($info)){ return '账户信息不存在'; } session([ 'user_id' => $info->id, 'openid' => $info->openid, 'is_login' => true ]); return true; } }

接下来就是使用授权,创建一个公共的控制器,需要微信授权才能看到的信息都需要过这个公共的控制器。比如创建一个CommonController.php
// 判断是否小程序授权过 class CommonController { // 登录验证openid public function __construct(){ // 接收验证登录的参数 $data = https://www.it610.com/Request::getData(['token', ]); if(empty($data['token'])){ return \Response::echoError('请输入授权token参数!'); } $res = Model('User') ->where([ 'token' => $data['token'] ]) ->select('id') ->first(); if(!$res){ return \Response::echoError('请先授权!'); }else{ //保存当前用户登录信息 $loginLogic = new LoginLogic(); $loginLogic->save($result_res->id); } }

【PHP快速实现微信小程序授权】

    推荐阅读