input('client_id'); $username = $request->input('username'); $password = $request->input('password'); // 分割 username $usernames = explode('.', $username); $module_id = $usernames[0] ?? null; $device_id = $usernames[1] ?? null; $module = Module::where('id', $module_id)->first(); if (!$module) { return $this->ignore(); } // 如果没有设置 device_id,那么就是模块自己的连接 if (!$device_id) { // 让 api_token 可见 $module->makeVisible('api_token'); // 比较 api_token if ($module->api_token == $password) { return $this->allow(); } else { return $this->deny(); } } else { // 如果设置了 device_id,那么就是设备的连接 // 此时,我们得联系模块,让模块去验证设备。 $response = $module->baseRequest('post', 'mqtt/authentication', [ 'client_id' => $client_id, 'device_id' => $device_id, 'password' => $password, ]); if ($response['status'] === 200) { return $this->allow(); } else { return $this->deny(); } } } public function authorization(Request $request) { // 禁止订阅保留的 if ($request->input('topic') == '$SYS/#') { return $this->deny(); } $action = $request->input('action'); $client_id = $request->input('client_id'); $username = $request->input('username'); $topic = $request->input('topic'); if ($topic === '#') { return $this->deny(); } // 使用 / 分割 topic $topics = explode('/', $topic); $usernames = explode('.', $username); $module_id = $usernames[0] ?? null; $device_id = $usernames[1] ?? null; $module = Module::where('id', $module_id)->first(); if (!$module) { // 不属于我们管理,跳过。 // Log::debug('不属于我们管理,跳过。'); return $this->ignore(); } // 设备只能在自己的模块下发布消息 if ($action == 'publish') { if ($topics[0] !== $module_id) { // 但是,在拒绝之前,应该检查一下,是否有允许的模块 $allow = ModuleAllow::where('module_id', $topics[0])->where('allowed_module_id', $module_id)->exists(); if (!$allow) { return $this->deny(); } } } if (count($usernames) === 1) { // 是模块自己的连接 return $this->allow(); } // 其他情况,让模块去验证 // 联系模块,让模块去验证设备授权。 $response = $module->baseRequest('post', 'mqtt/authorization', [ 'client_id' => $client_id, 'device_id' => $device_id, 'type' => $action, 'topic' => $topic, ]); if ($response['status'] === 200) { return $this->allow(); } else { return $this->deny(); } } private function deny() { return response([ 'result' => 'deny', ], 200); } private function ignore() { return response([ 'result' => 'ignore', ], 200); } private function allow() { return response([ 'result' => 'allow', 'is_superuser' => false, ], 200); } }