我有一个通用的API调用,我想在数据库中的不同表中使用它。 这是 SQL 查询
SELECT * FROM $column_name WHERE step != Failed
我想通过做这样的事情来避免 sql 注入的可能性
var type = req.params.type;
var sql = 'SELECT * FROM ? WHERE step != FALSE';
postgres.client.query(sql, [ type ], function(err, results) {}
这不起作用,并引发语法错误。 我做了一些探索并尝试做 1 美元,然后??,而不是 ?但没有任何效果。 我确实验证了类型变量是正确的值。
当我运行这个时,
var type = req.params.type;
var sql = 'SELECT * FROM ' + type + ' WHERE step != FALSE';
postgres.client.query(sql, [ type ], function(err, results)
它工作正常。 这是怎么回事??
据我了解,您使用节点发布(别名:pg
)模块。
对于该模块,没有?
或??
替换。
您必须使用$N
表示法,但 pg 驱动程序不允许动态表名。
所以这里有解决方法:
1) 创建constants/tableNames.js
文件,其中包含允许使用的表名列表:
module.exports = [
'users',
'profiles',
... and etc tables that You have
];
2) 创建包含以下内容的db/queries/selectFromTable.js
,这些内容将负责查询生成,并在允许的表名中检查表名:
const tableNames = require('../../constants/tableNames.js');
module.exports = (tableName, queryTail = 'WHERE step != FALSE') => {
if (tableNames.includes(tableName)) {
return 'SELECT * FROM '+tableName+' '+queryTail;
}
return 'SELECT NULL';
};
3)并在您的代码中使用它,如示例所示:
const selectFrom = require('db/queries/selectFromTable.js');
app.get('/records/:table', async (req, res) => {
try {
const table = req.params.table;
const query = selectFrom(table);
const result = await postgres.client.query(query, []);
res.status(200).send(result.rows);
/**
* OR:
* const table = req.params.table;
* const something = req.query.something;
* const query = selectFrom(table, 'WHERE step != FALSE AND something = $1::text');
* const result = await postgres.client.query(query, [something]);
* res.status(200).send(result.rows);
*/
}
catch (error) {
res.status(500).send(error);
}
});