* API默认继承类 */ namespace app\common\controller; use app\common\model\SystemUser; use app\common\model\SystemMemberMiniapp; use app\common\model\SystemMemberWechatTpl; use app\common\facade\WechatProgram; use app\common\event\User; use think\facade\Request; use filter\Filter; use sign\Sign; class Api extends Base { protected $miniapp; //应用信息 protected $miniapp_id; //应用信息ID protected $member_miniapp; //应用信息(兼容处理) protected $member_miniapp_id; //应用信息ID(兼容处理) protected $token; //验证用户 protected $user; //登录后用户 /** * 初始化类 */ protected function initialize(){ parent::initialize(); if(!Request::param('sapixx/d',0)){ exit(json_encode(['code'=>403,'msg'=>'禁止非法访问'])); } $this->miniapp = $this->apiAccess(); if(!$this->miniapp){ exit(json_encode(['code'=>403,'msg'=>'应用停止服务'])); } $this->member_miniapp = $this->miniapp; //兼容处理 $this->member_miniapp_id = $this->miniapp->id; //兼容处理 $this->miniapp_id = $this->miniapp->id; $this->user = self::getUser(); $this->isAppTyes($this->miniapp->miniapp->types); //判断应用类型 } /** * 方法不存在 */ public function _empty(){ return enjson(403,'未找到API地址'); } /** * 读取小程序配置 * @return void */ public function config(){ $wxconfig = [ 'app_name' => $this->miniapp->appname, 'app_id' => $this->miniapp->id, 'sdk_app_id' => $this->miniapp->sdk_app_id, 'sdk_url' => $this->miniapp->sdk_url, 'navbar_color' => $this->miniapp->navbar_color ?: '#ffffff', 'navbar_style' => $this->miniapp->navbar_style ?: '#000000', ]; $tpl = SystemMemberWechatTpl::getConfig($this->miniapp_id); if($tpl){ $wxconfig['tplmsg'][] = $tpl->tplmsg_common_app; } return enjson(200,$wxconfig); } /** * 获取用户数据 * @return void */ public function getUserInfo(){ $userinfo = self::getUser(); if(!$userinfo){ return json(['code'=>401,'msg'=>'用户认证失败']); } $data['invite_code'] = $this->user->invite_code; $data['phone_uid'] = empty($this->user->phone_uid) ? '' : en_phone($this->user->phone_uid); $data['telphone'] = $this->user->phone_uid; $data['invite_code'] = $this->user->invite_code; $data['face'] = $this->user->face; $data['nickname'] = $this->user->nickname; $data['login_time'] = date('Y-m-d',$this->user->login_time); return enjson(200,$data); } /** * 微信小程序统一登录接口 */ public function miniappLogin($type = 'json'){ if(request()->isPost()){ $data = [ 'code' => Request::param('code/s'), 'user_info' => Request::param('user_info/s'), 'encrypted_data' => Request::param('encrypted_data/s'), 'iv' => Request::param('iv/s'), 'signature' => Request::param('signature/s'), 'official_uid' => Request::param('official_uid/s',''), 'invite_code' => Request::param('invite_code/s',''), ]; $validate = $this->validate($data,'Miniapp.login'); if(true !== $validate){ return enjson(403,$validate,[],$type); } $userInfo = json_decode(htmlspecialchars_decode($data['user_info']),true); if(empty($userInfo)){ return enjson(403,'用户登录失败',[],$type); } //判断是否开放平台应用(0是开发平台 1是独立应用) $rel = WechatProgram::isTypes($this->miniapp_id); if(!$rel){ return enjson(403,'管理员未授权应用接入',[],$type); } $miniapp = $rel->auth->session($data['code']); if(!empty($miniapp['errcode'])){ return enjson(403,'Token无效,请联系管理员',[],$type); } $nickName = Filter::filter_Emoji($userInfo['nickName']); //获取(注册/登录)数据 $regdata['miniapp_uid'] = $miniapp['openid']; $regdata['session_key'] = $miniapp['session_key']; $regdata['official_uid'] = $data['official_uid']; //绑定公众号的OPENID时候用的 $regdata['wechat_uid'] = empty($miniapp['unionid']) ? '' : $miniapp['unionid']; $regdata['nickname'] = $nickName ?? '微信-'.time(); $regdata['avatar'] = $userInfo['avatarUrl']; $regdata['miniapp_id'] = $this->miniapp_id; $regdata['invite_code'] = $data['invite_code']; //邀请码 //判断是登录还是注册 $uid = SystemUser::wechatReg($regdata); if(!$uid){ return enjson(403,'用户认证失败',[],$type); } //保持注册记录 User::setLogin(['id'=> $uid,'nickname' => $nickName]); //返回信息 $return_data['token'] = WechatProgram::createToken(['miniapp_id' => $this->miniapp_id,'uid' => $uid,'miniapp_uid' => $miniapp['openid'],'service_id' => $this->miniapp->service_id]); $return_data['uid'] = $uid; $return_data['ucode'] = create_code($uid); $return_data['session_id'] = session_id(); return enjson(200,'登录成功',$return_data,$type); }else{ return $this->error("404 NOT FOUND"); } } /** * 生成小程序码 * @param [array] $scene 格式的参数 * @param [string] $page 小程序路径 * @return void */ public function MiniProgramCode(array $scene, $page, $name){ if(request()->isPost()){ $filepath = PATH_RES.'qrcode/'; $response = WechatProgram::isTypes($this->miniapp_id)->app_code->getUnlimit(http_build_query($scene),['page' => Filter::filter_escape($page)]); if ($response instanceof \EasyWeChat\Kernel\Http\StreamResponse) { $filename = $response->saveAs($filepath,md5($name)); $path = '/' . str_replace('\\', '/', substr($filepath.$filename,strlen(PATH_PUBLIC))); return json(['code' => 200, 'msg' => '成功', 'data' => Request::root(true).$path]); } return enjson(404,'您的应用未上线'); } } /** * 生成小程序码二维码 * @param [array] $scene 格式的参数 * @param [string] $page 小程序路径 * @return void */ public function MiniProgramQrCode(array $scene, $page, $name){ $filepath = PATH_RES.'qrcode/'; $response = WechatProgram::isTypes($this->miniapp_id)->app_code->getQrCode($page.'?'.http_build_query($scene)); if ($response instanceof \EasyWeChat\Kernel\Http\StreamResponse) { $filename = $response->saveAs($filepath,md5($name)); $path = '/' . str_replace('\\', '/', substr($filepath.$filename, strlen(PATH_PUBLIC))); return json(['code' => 200, 'msg' => '成功', 'data' => Request::root(true).$path]); } return enjson(404,'您的应用未上线'); } /** * 禁止用户登录 */ protected function isUserAuth($code = 401){ if(!$this->user){ exit(json_encode(['code' => $code,'msg'=>'用户认证失败'])); } } /** * 接口验证 * @param mixed $var 签名验证的参数 * @return array */ protected function apiSign($var = [],$signType = 'md5'){ $sign = Request::param('sign/s'); //获取签名 $publickey = Request::param('publickey/s'); //获取公钥 if(empty($sign)){ $code = 401; $msg = '没有验证签名'; }else{ $secret = $this->miniapp->service_id; if(empty($publickey) && empty($secret)){ $code = 403; $msg = '签名秘钥或公钥错误'; }else{ $var['sign'] = $sign; $var['publickey'] = $publickey; $sign = Sign::makeSign($var,$secret,$signType); if($var['sign'] == $sign){ $code = 200; $msg = '成功'; }else{ $code = 403; $msg = '参数验证失败'; } } } if($code != 200){ exit(json_encode(['code' => $code,'msg' => $msg])); } return ['code' => $code,'msg' => $msg]; } /** * 接口验证 * @param mixed $var 签名验证的参数 * @return array */ protected function makeSign($var = [],$secret = null,$signType = 'md5'){ if(empty($secret)){ $secret = $this->miniapp->service_id; } $var['sign'] = Sign::makeSign($var,$secret,$signType); return $var; } /** * 如果增加双向验证请在这里增加 * 增加服务器登录安全认证 * @return void */ protected function getUser(){ $rel = WechatProgram::checkToken(['service_id' => $this->miniapp->service_id,'token'=>$this->token]); if($rel){ return SystemUser::where(['id' => $rel['uid'],'is_lock' => 0])->find(); } return; } }