前言:零点博客的折腾之路
最近在零点博客维护一套CMS时,为了方便给不同客户导出数据,我决定自己写一个在线JSON转SQL的工具。听起来挺简单,但真干起来发现坑不少。尤其是涉及到SQL语句的拼接和数据库交互时,安全性是第一位的。今天就来复盘一下这个过程,从后端C#解析到前端HTML展示,再到核心的SQL语句编写,咱们一步步来。
一、 后端架构:C#与MySQL的对接
这工具的后端我选用了熟悉的C# (.NET Core)。主要流程就是:接收前端传来的JSON数据 -> 解析 -> 验证 -> 拼接成SQL语句 -> 执行。
咱们先看怎么把JSON转成List对象,这里用到了Json.NET库:
// 简单的实体映射
var jsonStr = "{\"id\":1,\"name\":\"测试\"}";
var obj = JsonConvert.DeserializeObject<MyModel>(jsonStr);
拿到数据后,就是最关键的一步:如何把数据变成可执行的SQL语句?
二、 核心痛点:正则与SQL语句拼接
在拼接SQL语句前,必须做数据清洗。很多非结构化数据里会有特殊字符,比如引号、分号,这会直接导致SQL报错或更严重的注入问题。
我写了一个简单的正则表达式来清洗字符串:
string CleanSql(string input)
{
// 将单引号转义,防止SQL语法错误
return Regex.Replace(input, @"'", "''");
}
清洗完数据后,我开始组装SQL语句。最基础的做法是用字符串拼接:
string sql = $"INSERT INTO users (name, age) VALUES ('{CleanSql(user.Name)}', {user.Age})";
但是,这种写法在SQL注入攻击面前就像纸糊的一样。为了演示效果,大家可以测试一下这个漏洞:
// 输入: 123' OR '1'='1
// 注入后的SQL语句会变成:
// INSERT INTO users (name, age) VALUES ('123' OR '1'='1', ...)
三、 避坑指南:预处理语句与参数化查询
为了避免这种隐患,我们必须抛弃字符串拼接,改用SQL注入防护。在C#连接MySQL时,使用预处理语句是标准做法。
修改后的代码如下,重点在于将参数与SQL结构分离:
// 使用 MySqlCommand 和 参数化查询
string sql = "INSERT INTO users (name, age) VALUES (@name, @age)";
using (var conn = new MySqlConnection(connString))
{
conn.Open();
using (var cmd = new MySqlCommand(sql, conn))
{
// 绑定参数,数据库会自动处理转义
cmd.Parameters.AddWithValue("@name", CleanSql(user.Name));
cmd.Parameters.AddWithValue("@age", user.Age);
int rows = cmd.ExecuteNonQuery();
Console.WriteLine($"执行成功,影响行数: {rows}");
}
}
你会发现,无论输入什么特殊的字符串,数据库都会把它当作普通文本处理,而不是可执行的代码。这就是SQL语句安全的根本。
四、 前端交互:JS解析JSON与反馈
工具做好后,前端负责把JSON发给后端。这里前端用原生JS解析JSON非常快:
// 模拟发送请求
fetch('/api/convert-to-sql', {
method: 'POST',
body: JSON.stringify(jsonData)
});
后端返回生成的SQL语句,前端再用正则高亮显示,让用户复制。
五、 总结与复盘
开发这个工具最大的收获就是深刻理解了SQL语句的生命周期:从字符串拼接的风险,到预处理语句的救赎。
- 对于普通开发,尽量少用字符串拼接写SQL语句。
- 对于数据库操作,永远使用参数化查询。
- 在写爬虫或接口时,输入数据的清洗至关重要。
如果你在开发EMLOG插件或自定义CMS时遇到类似的坑,欢迎在零点博客留言交流。希望这份复盘对大家有帮助!



评论一下吧
取消回复