2024-05-30 19:16:59 +08:00
|
|
|
|
<?php
|
|
|
|
|
|
|
|
|
|
namespace Api\Controller;
|
|
|
|
|
|
|
|
|
|
use Think\Controller;
|
|
|
|
|
|
|
|
|
|
use Firebase\JWT\JWT;
|
2024-06-04 14:43:23 +08:00
|
|
|
|
use Firebase\JWT\Key;
|
2024-05-30 19:16:59 +08:00
|
|
|
|
|
2024-06-05 20:20:00 +08:00
|
|
|
|
use PhpMqtt\Client\MqttClient;
|
|
|
|
|
use PhpMqtt\Client\Exceptions\MqttClientException;
|
|
|
|
|
use PhpMqtt\Client\ConnectionSettings;
|
|
|
|
|
|
2024-05-30 19:16:59 +08:00
|
|
|
|
class PublicController extends Controller
|
|
|
|
|
{
|
2024-06-04 14:43:23 +08:00
|
|
|
|
protected $openid; // 用户openid
|
|
|
|
|
protected $session_key; // 用户session_key
|
2024-05-30 19:16:59 +08:00
|
|
|
|
//初始化
|
|
|
|
|
public function _initialize()
|
|
|
|
|
{
|
2024-06-05 16:39:48 +08:00
|
|
|
|
// 获取请求头中的 Token
|
|
|
|
|
$token = isset($_SERVER['HTTP_TOKEN']) ? $_SERVER['HTTP_TOKEN'] : null;
|
|
|
|
|
// 获取 jwt 密钥
|
|
|
|
|
$jwtKey = C('jwtKey');
|
2024-06-04 14:43:23 +08:00
|
|
|
|
try {
|
2024-06-05 16:39:48 +08:00
|
|
|
|
// 解码 JWT Token
|
|
|
|
|
$decoded = JWT::decode($token, new Key($jwtKey, 'HS256'));
|
|
|
|
|
// Token 没有过期,继续处理
|
|
|
|
|
$this->openid = $decoded->openid;
|
|
|
|
|
$this->session_key = $decoded->session_key;
|
|
|
|
|
} catch (\Firebase\JWT\ExpiredException $e) {
|
|
|
|
|
// Token 过期
|
|
|
|
|
echo json_encode(array('status' => -1, 'msg' => 'Token 已过期'));
|
|
|
|
|
exit();
|
|
|
|
|
} catch (\Exception $e) {
|
|
|
|
|
// 其他 JWT 解码错误
|
2024-06-05 16:49:59 +08:00
|
|
|
|
echo json_encode(array('status' => -1, 'msg' => 'Token 解码失败'));
|
2024-06-04 14:43:23 +08:00
|
|
|
|
exit();
|
2024-06-05 16:47:24 +08:00
|
|
|
|
} catch (\TypeError $e) {
|
|
|
|
|
// 处理 Token 为 null 或者不是字符串的情况
|
2024-06-05 16:49:59 +08:00
|
|
|
|
echo json_encode(array('status' => -1, 'msg' => 'Token 无效'));
|
2024-06-05 16:47:24 +08:00
|
|
|
|
exit();
|
2024-06-04 14:43:23 +08:00
|
|
|
|
}
|
2024-05-30 19:16:59 +08:00
|
|
|
|
}
|
|
|
|
|
//远程调取页面 访问API
|
|
|
|
|
protected function apiUrl($url)
|
|
|
|
|
{
|
|
|
|
|
$ch = curl_init();
|
|
|
|
|
curl_setopt($ch, CURLOPT_URL, $url);
|
|
|
|
|
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
|
|
|
|
|
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
|
|
|
|
|
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
|
|
|
|
|
$output = curl_exec($ch);
|
|
|
|
|
curl_close($ch);
|
|
|
|
|
$jsoninfo = json_decode($output, true);
|
|
|
|
|
return $jsoninfo;
|
|
|
|
|
}
|
|
|
|
|
/**
|
|
|
|
|
* @description: 构建token
|
2024-06-20 17:10:35 +08:00
|
|
|
|
* @param {array} data 要存储在 JWT 中的数据,键值对形式 ps:这里可以传exp 来覆盖默认的过期时间
|
2024-05-30 19:16:59 +08:00
|
|
|
|
* @return {*} token
|
|
|
|
|
*/
|
2024-06-20 17:10:35 +08:00
|
|
|
|
protected function makeToken($data = [])
|
2024-05-30 19:16:59 +08:00
|
|
|
|
{
|
|
|
|
|
// 定义密钥,应该使用安全的随机字符串并妥善保管
|
|
|
|
|
$jwtKey = C('jwtKey');
|
|
|
|
|
$currtime = time();
|
2024-06-20 17:10:35 +08:00
|
|
|
|
|
|
|
|
|
// 默认的数据
|
|
|
|
|
$defaultData = [
|
|
|
|
|
'iat' => $currtime, // 签发时间(时间戳)
|
2024-05-30 19:16:59 +08:00
|
|
|
|
'iss' => 'jwt_admin', // 签发者
|
2024-06-20 17:10:35 +08:00
|
|
|
|
'nbf' => $currtime, // 在此时间之前不可用 (这里是2秒以内)
|
2024-06-05 16:54:02 +08:00
|
|
|
|
'exp' => strtotime('tomorrow'), //过期时间 到第二天凌晨
|
2024-06-20 17:10:35 +08:00
|
|
|
|
'jti' => md5(uniqid('JWT') . $currtime), // JWT ID:令牌的唯一标识符
|
2024-05-30 19:16:59 +08:00
|
|
|
|
];
|
2024-06-20 17:10:35 +08:00
|
|
|
|
|
|
|
|
|
// 合并默认数据和传递的数据
|
|
|
|
|
$tokenData = array_merge($defaultData, $data);
|
|
|
|
|
|
2024-05-30 19:16:59 +08:00
|
|
|
|
// 使用密钥和 HS256 算法对数据进行编码生成 JWT
|
2024-06-20 17:10:35 +08:00
|
|
|
|
return JWT::encode($tokenData, $jwtKey, 'HS256');
|
2024-05-30 19:16:59 +08:00
|
|
|
|
}
|
|
|
|
|
/**
|
|
|
|
|
* @description: 将手机号的倒数第 5 位到第 8 位替换成星号
|
|
|
|
|
* @param string $phoneNumber 完整的手机号
|
|
|
|
|
* @return string 处理后的手机号
|
|
|
|
|
*/
|
|
|
|
|
protected function maskPhoneNumber($phoneNumber)
|
|
|
|
|
{
|
|
|
|
|
// 去掉手机号中的+号以便处理
|
|
|
|
|
$cleanPhoneNumber = str_replace('+', '', $phoneNumber);
|
|
|
|
|
|
|
|
|
|
// 判断手机号长度(带国家区号和不带国家区号的情况)
|
|
|
|
|
if (strlen($cleanPhoneNumber) > 11) { // 带国家区号的手机号
|
|
|
|
|
$maskedPhoneNumber = substr_replace($cleanPhoneNumber, '****', -8, 4);
|
|
|
|
|
return '+' . $maskedPhoneNumber;
|
|
|
|
|
} elseif (strlen($cleanPhoneNumber) === 11) { // 不带国家区号的手机号
|
|
|
|
|
return substr_replace($cleanPhoneNumber, '****', -8, 4);
|
|
|
|
|
} else {
|
|
|
|
|
// 非法手机号长度,返回原始号码
|
|
|
|
|
return $phoneNumber;
|
|
|
|
|
}
|
|
|
|
|
}
|
2024-06-05 20:20:00 +08:00
|
|
|
|
/**
|
|
|
|
|
* @description: 连接mqtt服务器 并向指定主题发布信息
|
|
|
|
|
* @param string $topic mqtt主题
|
|
|
|
|
* @param string $msg 要发布的主题
|
|
|
|
|
*/
|
|
|
|
|
protected function publish($topic, $msg)
|
|
|
|
|
{
|
|
|
|
|
$server = C('mqtt')['server']; // MQTT 代理地址
|
|
|
|
|
$port = C('mqtt')['port']; // MQTT 代理端口
|
|
|
|
|
$clientId = C('mqtt')['client_id']; // 客户端 ID
|
|
|
|
|
$username = C('mqtt')['username']; // 用户名(如果需要)
|
|
|
|
|
$password = C('mqtt')['password']; // 密码(如果需要)
|
|
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
// 创建连接设置对象
|
|
|
|
|
$settings = (new ConnectionSettings)->setUsername($username)->setPassword($password);
|
|
|
|
|
// 实例化 MQTT 客户端
|
|
|
|
|
$mqtt = new MqttClient($server, $port, $clientId);
|
|
|
|
|
// 连接到 MQTT 代理
|
|
|
|
|
$mqtt->connect($settings);
|
|
|
|
|
// 检查是否连接成功
|
|
|
|
|
if ($mqtt->isConnected()) {
|
|
|
|
|
// 发布消息到指定的主题 ps:主题 信息 qos
|
|
|
|
|
$mqtt->publish($topic, $msg, 0);
|
|
|
|
|
// 断开连接
|
|
|
|
|
$mqtt->disconnect();
|
|
|
|
|
} else {
|
|
|
|
|
echo "连接失败";
|
|
|
|
|
}
|
|
|
|
|
} catch (MqttClientException $e) { //连接失败
|
|
|
|
|
echo "Could not connect to MQTT broker: " . $e->getMessage();
|
|
|
|
|
}
|
|
|
|
|
}
|
2024-05-30 19:16:59 +08:00
|
|
|
|
}
|