getLoginAuthCodeByUid($decode['sub'],$port); // 不存在登录信息,提示失败 if( !$memAuthcode ) throw new LoginException("login_miss"); // 如果是32位的话 if( strlen($memAuthcode) == 32 ) $authcode = md5($authcode); // 如果存在登录数据,并且不是当前用户的缓存登录,提示失败 if( $authcode != $memAuthcode ) throw new LoginException("login_miss"); // 返回用户ID return $decode['sub']; } /** * 登录验证 * * @return Int 用户ID * */ public function getUid($authcode=''){ // 默认接参 $authcode = $authcode ? $authcode : request('authcode',''); // 如果没有有登录信息 if( !$authcode ) return 0; // 尝试执行 try { // 解码 $decode = AccessToken::decode($authcode); // 错误返回 if( isset($decode['error']) ) return 0; // 如果没有过期时间,过期处理 if( empty($decode['exp']) ) return 0; // 如果过期,过期处理 if( $decode['exp'] <= time() ) return 0; // 登录的商户ID $loginCompanyId = empty($decode['company_id']) ? 0 : $decode['company_id']; // 如果登录的商户不一致,提醒重新登录 if( $loginCompanyId != request('company_id',0)) return 0; // 返回用户ID return $decode['sub']; } catch (\Throwable $th) { // 返回0 return 0; } } /** * 接口验签 * * @param [Array] $data 参与验证的参数 * * * */ public function verify_sign($data=[]){ // 获取参数 $data = $data ? $data : request()->all(); // 没有签名 if( empty($data['sign']) ) throw new VerifySignException('sign_miss'); // 没有签名 if( empty($data['appid']) ) throw new VerifySignException('appid_miss'); // 传了key if( !empty($data['key']) ) throw new VerifySignException('appkey_no_allow'); // 没有请求时间 if( empty($data['timestamp']) ) throw new VerifySignException('sign_timeout'); // 请求过期 if( abs(time() -$data['timestamp'] ) > 86400 ) throw new VerifySignException('sign_timeout'); // 已使用过的签名不允许二次使用 $this->checkSignUsed($data['sign']); // 从配置读取接口验签应用数据 $verify = ['2DEA6A19BDCA383B'=>'FD6F87E89EABAF1063A849D971B68618']; // 是否有对应的appid if( !isset($verify[$data['appid']]) ) throw new VerifySignException('appid_nofund'); // appkey $appkey = $verify[$data['appid']]; // 获得签名参数数据 $sign = $data['sign']; // 删除传入签名参数 unset($data['sign']); // 删除上传文件的字段 if( isset($data['file'])) unset($data['file']); // 键名字典排序 ksort($data); // 空字符串 $param = ''; // 循环参数对象,拼接url字符串 foreach ( $data as $key => $value ) { // 如果键值为空(空字符串 空数组 空集合 空对象 字符串0 数字0 NULL FALSE),此参数省略;另 '000' 这类0组成的字符串 不为空 if( strtolower($value) == 'false' || strtolower($value) == 'null' || empty($value) || ( is_numeric($value) && $value == 0 && substr_count($value,'.') == 1 ) ) continue; // 判断键值是否是数组,对象 ,如果是的话,键值转json字符串 if( is_array( $value ) || is_object($value) ) $value = json_encode($value,JSON_UNESCAPED_SLASHES|JSON_UNESCAPED_UNICODE); // 如果键值为真则 键值转md5加密(此处小写) 为假则直接拼接,0特殊处理 $param .= '&'.$key.'='.$value; } // 转码 $param = ltrim($param,'&'); // 解码 $param = rawurldecode($param); // 拼接私钥数据 $param .= '&key='.$appkey; // 比对签名,数据加密(MD5后转大写),$param.'=>'.strtoupper(md5($param)).'=>'.$sign if( strtoupper(md5($param)) != $sign) throw new VerifySignException('sign_error'); // 验签通过 return ['success'=>'验签成功']; } /** * 判断签名是否已用 * * @param [Array] $data 参与验证的参数 * * * */ public function checkSignUsed($sign='') { // 获取签名 $is_used = cache('ApiSign:'.$sign); // 如果签名已用 if( $is_used ) throw new VerifySignException('sign_used'); // 存储已经验证过的签名 cache(['ApiSign:'.$sign=>$sign],60); // 成功返回 return ['success'=>'签名可用']; } /** * 接口验签 * * @param Array $data 参与验证的参数 * * * */ public function sign($data) { // 返回加密结果 return ApiSign::encode($data); } /** * 店铺验证 * */ public function checkShop($uid='', $shopId=''){ // 商户ID $companyId = request('company_id',0); // 默认接参 $shopId = $shopId ? $shopId : request('shop_id',0); // 访问记录 $CustomShopRecord = (new CustomShopRecord()); // 如果没有店铺,获取用户记录最后访问的店铺 if (!$shopId) $shopId = $uid ? $CustomShopRecord->query()->where(['company_id'=>$companyId,'custom_uid'=>$uid])->orderByDesc('visit_time')->value('shop_id') : $shopId; // 如果还是没有店铺,获取商户下的第一个店铺 if (!$shopId) $shopId = (new Shop())->query()->where(['company_id'=>$companyId])->orderBy('id')->value('id'); // 如果有shopId if ( $shopId && $uid ) { // 判断是不是有对应的店铺数据 $recordId = $CustomShopRecord->where(['custom_uid'=>$uid,'company_id'=>$companyId,'shop_id'=>$shopId])->value('id'); // 更新还是新增 $recordId ? $CustomShopRecord->edit($recordId,['visit_time'=>time()]) : $CustomShopRecord->add(['custom_uid'=>$uid,'shop_id'=>$shopId,'company_id'=>$companyId,'visit_time'=>time()]); } // 返回 return ['shop_id'=>$shopId,'company_id'=>$companyId]; } }