123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256 |
- <?php
- /**
- * @copyright Copyright (c) 2018 https://www.sapixx.com All rights reserved.
- * @license Licensed (http://www.apache.org/licenses/LICENSE-2.0).
- * @author pillar<ltmn@qq.com>
- * 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;
- }
- }
|