【发布时间】:2021-01-09 00:26:12
【问题描述】:
我现在正在尝试如何将 Google 云功能用作我的 IOT 应用程序的一部分。
但是当我向触发器端点发送 JSON POST 时遇到问题。有时它工作得很好,有时有效载荷十六进制在中间被切断。
例如,原始的有效载荷十六进制为“0011029e02ffb1ffd6ffd8ffdaffe0fff500000008”,有时在保存到数据库时会突然变为“0011029e02ffb1”。
我测试端点的方式是使用 Postman 发送 HTTP POST 并包含以下数据。
{
"DevEUI_uplink": {
"DevEUI": "BC9740FFFE10549E",
"payload_hex": "0011029e02ffb1ffd6ffd8ffdaffe0fff500000008",
}}
云函数内部是nodejs12代码:
/**
* Responds to any HTTP request.
*
* @param {!express:Request} req HTTP request context.
* @param {!express:Response} res HTTP response context.
*/
const moment = require("moment");
const mysql = require("mysql");
require("dotenv").config();
exports.saveFunction = (req, res) => {
let now = moment().format('YYYY-MM-DD HH:mm:ss');
let deveui = req.body.DevEUI_uplink.DevEUI;
let payload = req.body.DevEUI_uplink.payload_hex;
function convertTempData(data) {
data = parseInt(data, 16);
if ((data & 0x8000) > 0) {
data = data - 0x10000;
}
return data;
}
// Slice the Request Data
let raw_payload = payload;
let version = parseInt(payload.slice(0, 2), 16);
let gem1 = parseInt(payload.slice(2, 4), 16);
let gem2 = parseInt(payload.slice(4, 6), 16);
let battery = parseInt(payload.slice(6, 8), 16) / 2;
let payload_id = parseInt(payload.slice(8, 10), 16);
let tempNow = convertTempData(payload.slice(10, 14));
let tempVar1 = convertTempData(payload.slice(14, 18));
let tempVar2 = convertTempData(payload.slice(18, 22));
let tempVar3 = convertTempData(payload.slice(22, 26));
let tempVar4 = convertTempData(payload.slice(26, 30));
let tempVar5 = convertTempData(payload.slice(30, 34));
let tempVar6 = convertTempData(payload.slice(34, 38));
let tempVar7 = convertTempData(payload.slice(38, 42));
// Connection String
const conn = mysql.createConnection({
host: process.env.SERVER_HOST,
user: process.env.SERVER_USER,
password: process.env.SERVER_PASS,
database: process.env.SERVER_DB,
port: process.env.SERVER_PORT,
});
conn.connect(function (err) {
if (err) {
return res
.status(404)
.json({ message: "Invalid Request", error: err.message });
}
var sqlcoms =
"UPDATE sd_payload SET payload = '" +
raw_payload +
"' , version='" +
version +
"', gem1='" +
gem1 +
"' , gem2='" +
gem2 +
"' , battery='" +
battery +
"',payload_id='" +
payload_id +
"',tempNow='" +
tempNow +
"',tempVar1='" +
tempVar1 +
"',tempVar2='" +
tempVar2 +
"',tempVar3='" +
tempVar3 +
"',tempVar4='" +
tempVar4 +
"',tempVar5='" +
tempVar5 +
"',tempVar6='" +
tempVar6 +
"',tempVar7='" +
tempVar7 +
"',updated_at='" +
now +
"' WHERE DevEUI = '" +
deveui +
"'";
conn.query(sqlcoms, function (err, result) {
if (err) {
return res
.status(404)
.json({ message: "Invalid Request", error: err.message });
}
return res.status(201).json(result);
});
});
};
我想将整个有效负载保存到数据库中以进行检查。您能否告知为什么 post json 正文在某些插入中被中途剪切,而某些插入将是完整的?
【问题讨论】:
-
您是否记录了有效负载以查看其是否正确?此外,您的 SQL 查询容易受到 SQL injection 的攻击,因为您只是将查询连接在一起的字符串。尝试将此密钥添加到您的 JSON 有效负载中,例如:
"test": " ' WHERE 1=1;-- "- 它会覆盖所有 sd_payload。使用?占位符,如node-mysql的文档中所述:github.com/mysqljs/mysql#performing-queries -
哦,我从没想过这样做的安全性,但我想这是一个很好的开始。谢谢你的提醒。我会试试这个。关于有效负载,当我记录传入缓冲区时,数据已经被切碎了,所以可能是 Lora 网关问题......不过,谢谢提示!
-
嘿@Metono,你能解决这个问题吗?
-
遗憾的是还没有,我不确定在来自网关的发布请求数据期间是否存在问题,或者我对进入谷歌云功能/cloudrun 的发布请求做错了什么。当我记录所有通过 Lora 网关传递到 RequestBin 或 Laravel 端点的请求时,一切都是正确的。与 GCP 云功能/cloudrun 端点相比,我看到的有效负载数据不完整。有什么想法可以在 GCP 中检查吗?日志显示我只收到不完整的 json 数据
标签: javascript node.js json google-cloud-functions