// +---------------------------------------------------------------------- declare (strict_types=1); namespace app\store\service; use app\store\model\store\Api as ApiModel; use app\store\model\store\MenuApi as MenuApiModel; use app\store\model\store\UserRole as UserRoleModel; use app\store\model\store\RoleMenu as RoleMenuModel; use app\store\service\store\User as StoreUserService; /** * 商家后台权限业务 * Class Auth * @package app\admin\service */ class Auth { // 实例句柄 static public $instance; // 商家登录信息 private $store; // 商家用户信息 private $user; // 商家用户权限url private array $apiUrls = []; /** * 公有化获取实例方法 * @return Auth */ public static function getInstance(): self { if (!(self::$instance instanceof Auth)) { self::$instance = new self; } return self::$instance; } /** * 私有化构造方法 * Auth constructor. */ private function __construct() { // 商家登录信息 $this->store = StoreUserService::getLoginInfo(); // 当前用户信息 !empty($this->store) && $this->user = $this->store['user']; } /** * 私有化克隆方法 */ private function __clone() { } /** * 验证指定url是否有访问权限 * @param $url * @param bool $strict 严格模式($url必须全部有权) * @return bool * @throws \think\db\exception\DataNotFoundException * @throws \think\db\exception\DbException * @throws \think\db\exception\ModelNotFoundException */ public function checkPrivilege($url, bool $strict = true): bool { if (!is_array($url)) { return $this->checkAccess($url); } foreach ($url as $val) { $status = $this->checkAccess($val); if ($strict && !$status) return false; if (!$strict && $status) return true; } return true; } /** * 验证url的权限 * @param $url * @return bool * @throws \think\db\exception\DataNotFoundException * @throws \think\db\exception\DbException * @throws \think\db\exception\ModelNotFoundException */ private function checkAccess($url): bool { // 域名白名单 // config/allowapi.php $allowApis = config('allowapi'); // 验证当前请求是否在白名单 if (in_array($url, $allowApis)) { return true; } // 用户不存在 禁止访问 if (empty($this->user)) { return false; } // 超级管理员无需验证 if ($this->user['is_super']) { return true; } // 通配符支持 foreach ($allowApis as $action) { if (strpos($action, '*') !== false && preg_match('/^' . str_replace('/', '\/', $action) . '/', $url) ) { return true; } } // 获取当前用户的权限url列表 if (!in_array($url, $this->getAccessUrls())) { return false; } return true; } /** * 获取当前用户的权限url列表 * @return array * @throws \think\db\exception\DataNotFoundException * @throws \think\db\exception\DbException * @throws \think\db\exception\ModelNotFoundException */ private function getAccessUrls(): array { if (empty($this->apiUrls)) { // 获取当前用户的角色ID集 $roleIds = UserRoleModel::getRoleIdsByUserId($this->user['store_user_id']); // 获取已分配的菜单ID集 $menuIds = RoleMenuModel::getMenuIds($roleIds); // 获取已分配的API的ID集 $apiIds = MenuApiModel::getApiIds($menuIds); // 获取当前角色所有权限链接 $this->apiUrls = ApiModel::getApiUrls($apiIds); } return $this->apiUrls; } }