147 lines
3.7 KiB
PHP
147 lines
3.7 KiB
PHP
<?php
|
||
|
||
namespace App\Http\Controllers\Application;
|
||
|
||
use App\Http\Controllers\Controller;
|
||
use App\Models\Module;
|
||
use Illuminate\Http\Request;
|
||
use Illuminate\Support\Facades\Log;
|
||
|
||
class MqttAuthController extends Controller
|
||
{
|
||
//
|
||
|
||
public function authentication(Request $request)
|
||
{
|
||
//
|
||
$client_id = $request->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');
|
||
|
||
// 使用 / 分割 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) {
|
||
// Log::debug('设备只能在自己的模块下发布消息');
|
||
return $this->deny();
|
||
}
|
||
}
|
||
|
||
if (count($usernames) === 1) {
|
||
// 是模块自己的连接
|
||
return $this->allow();
|
||
}
|
||
|
||
// Log::debug('联系模块。');
|
||
|
||
// 联系模块,让模块去验证设备授权。
|
||
$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);
|
||
}
|
||
}
|