request->hostInfo, Yii::app()->params['url'])) { throw new CHttpException(403, '非法访问'); } header("Access-Control-Allow-Origin:" . Yii::app()->request->hostInfo); } header("Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS"); header("Access-Control-Allow-Headers: Content-Type, Authorization, Cookie"); if ($_SERVER['REQUEST_METHOD'] == 'OPTIONS') { exit(0); // 预检请求直接返回 } } public function checkSign() { if (!\Yii::app()->request->isPostRequest || !empty($_FILES)) { return true; } if (!isset($_POST['sign'])) { return false; } if (!isset($_POST['timestamp']) || $_POST['timestamp'] < time() - 10) { return false; } $postSign = $_POST['sign']; unset($_POST['sign']); // 签名不计算sign $stringArray = []; // 对参与签名的参数进行排序 foreach ($_POST as $k => $v) { if (is_array($v)) { $v = implode(',', $v); } $stringArray[] = $k . '=' . trim($v); } sort($stringArray, SORT_STRING); $query = implode('&', $stringArray) . 'qwer'; $query = str_replace(["\r", "\n"], '', $query); $sign = strtoupper(hash('sha256', $query)); if ($sign != $postSign) { Logger::errorMult('签名错误', $query, $sign); return false; } return true; } /** * 限制操作频率 * @param $second * @return void|null * @throws RedisException */ public function dobuleCheck($second = 3) { $key = 'dobule_' . $this->_userId; if (!RedisInstance::getInstance()->setNx($key, 1, $second)) { return Helper::error('操作过于频繁'); } } /** * @throws CHttpException */ public function beforeAction($action): bool { $this->checkRequest(); $token = $_SERVER['HTTP_AUTHORIZATION']?? ''; $data = RedisInstance::getInstance()->get('user_token:'.$token); $this->_userId = $data['id']?? 0; Yii::app()->language = 'zh_cn'; $controller = Yii::app()->controller->id; $action = $this->getAction()->getId(); $path = strtolower($controller . '/'. $action); if( !in_array($controller, ['site']) &&!in_array($path, LewaimaiAdminPingtaiAuth::$noLoginRouters) && !$this->_userId ){ Helper::error('请先登入', 401); } if (!$this->checkSign()) { Helper::error('签名错误', 402); } // 获取权限相关数据 $this->_formatAuth(); if (!LewaimaiAdminPingtaiAuth::adminAuth($controller, $action) && ($this->_userId && $this->_userId != 1) ) { Helper::error('您没有相应的权限'); } return true; } private function _formatAuth(): void { $key = 'user_auth_' . $this->_userId; $data = RedisInstance::getInstance()->get($key); if (!$data) { $user = DB::getInfoWithCriteria('useradmin', DbCriteria::simpleCompare(['u.id' => $this->_userId]) ->setAlias('u') ->setSelect('company_ids, school_ids, date_auth_type, auth_ids,cities') ->setJoin('left join wx_role r ON r.id = u.role_id')); if (!$user) { throw new CHttpException(401, '用户不存在'); } $this->authIds = $user['auth_ids'] ? explode(',', $user['auth_ids']) : []; $this->authType = $user['date_auth_type']; if ($this->authType == AUTH_TYPE_COMPANY_SCHOOL) { $this->companyIds = $user['company_ids'] ? explode(',', $user['company_ids']) : []; $this->schoolIds = $user['school_ids'] ? explode(',', $user['school_ids']) : []; } elseif ($this->authType == AUTH_TYPE_CITY) { $cities = array_filter(explode(',', $user['cities'])); if ($cities) { $this->companyIds = Helper::arrayColumn(DB::getListWithCriteria('company', DbCriteria::simpleCompare(['is_del' => 0, 'city' => $cities])->setSelect('id')), 'id') ?: [-9999]; $this->schoolIds = Helper::arrayColumn(DB::getListWithCriteria('school', DbCriteria::simpleCompare(['is_del' => 0, 'city' => $cities])->setSelect('id')), 'id') ?: [-9999]; } else { $this->companyIds = [-9999]; $this->schoolIds = [-9999]; } } else { $this->companyIds = [-1]; $this->schoolIds = [-1]; } $json = json_encode([ 'authIds' => $this->authIds, 'companyIds' => $this->companyIds, 'schoolIds' => $this->schoolIds, 'authType' => $this->authType, ]); RedisInstance::getInstance()->set($key, $json, 86400); } else { $data = json_decode($data, true); $this->authIds = $data['authIds']; $this->companyIds = $data['companyIds']; $this->schoolIds = $data['schoolIds']; $this->authType = $data['authType']?? AUTH_TYPE_COMPANY_SCHOOL; } LewaimaiAdminPingtaiAuth::$authIds = $this->authIds; } public function clearAuth($id = 0) { $id = $id ? : $this->_userId; RedisInstance::getInstance()->delete('user_auth_' . $id); } public function clearAuthByCity(string $city): void { // 清除缓存 $cri = DbCriteria::simpleCompare(['status' => 1]) ->setSelect('id') ->addCondition("find_in_set('{$city}', cities)"); $users = DB::getListWithCriteria('useradmin', $cri)?:[]; Logger::errorMult('auth_change', $users); foreach ($users['records'] as $user) { $this->clearAuth($user['id']); } } public function getUserId() { return $this->_userId; } public function getSchoolFilter($filed = 'school_id'):?array { if ($this->_userId == 1 || in_array(-1, $this->companyIds)) { return null; } return $this->schoolIds; } public function checkSchoolId(int $id):bool { if ($this->_userId == 1 || in_array(-1, $this->schoolIds)) { return true; } return in_array($id, $this->schoolIds); } public function getCompanyFilter():?array { if ($this->_userId == 1 || in_array(-1, $this->companyIds)) { return null; } return $this->companyIds; } public function checkCompanyId(int $id):bool { if ($this->_userId == 1 || in_array(-1, $this->companyIds)) { return true; } return in_array($id, $this->companyIds); } }