| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151 | const router = require('express').Router();const bodyParser = require('body-parser')router.use(bodyParser.urlencoded({	extended: false}));router.use(bodyParser.json({ limit: '10mb' }));// 跨域参数配置// const allowCrossDomain = function (req, res, next) {//     res.header('Access-Control-Allow-Origin', '*');//     res.header('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE');//     res.header('Access-Control-Allow-Headers', 'Content-Type');//     res.header('Access-Control-Allow-Credentials', 'true');//     next();// };// router.use(allowCrossDomain)function goWrong(response,msg){    response.status(500)    response.json({        code:500,        mess:msg    })    return}const psqlDB = require("../../psql.service");/** * @api {post} /psql/select psql查询接口 * @apiSampleRequest /api/psql/select * @apiVersion 0.5.0 * @apiName psqlSELECT * @apiGroup psql * @apiParam {String} sql='SELECT * FROM "VrPanoLog" limit $1;' 仅限SQL的SELECT和WITH查询 * @apiParam {String} [params='[5]' ] 参数数组 * @apiSuccess {data} data 结果 * @apiSuccessExample Success-Response: *     HTTP/11 200 OK *     { *       "code": 200, *       "mess": "成功", *       "data": [ * ] *     } * @example curl -X POST 'http://127.0.0.1:1337/api/psql/select' -H 'Content-Type: application/json' --data '{"sql":"SELECT * FROM \"_User\" limit 5","params":[1]}' curl -X POST 'https://dev.fmode.cn/api/psql/select' -H 'Content-Type: application/json' --data '{"sql":"SELECT * FROM \"_User\" limit 5","params":[1]}' let response = await fetch(`https://dev.fmode.cn/api/psql/select`, {        headers: {            "Content-Type": "application/json"        },        body: JSON.stringify({"sql":"SELECT * FROM \"_User\" limit 5","params":[1]}),        method: "POST",        mode: "cors",        credentials: "omit"    }); let result = await response?.json(); console.log(result) */router.post('/select', async function (req, response) {    // 0.接收参数,并且校验    let sql = req.body.sql;    let token = req.body.token;    let params = req.body.params;    if(!sql){        goWrong(response,"缺少参数sql")        return;    }    // 2.分析查询参数    try{        if(params){            params = JSON.parse(params)        }        if(params&¶ms.length<1){            goWrong(response,"params参数必须为数组")            return;        }        let biggerSQL = sql.toUpperCase();        let checkArray = biggerSQL.split(" ")        if( // 过滤修改操作            biggerSQL.startsWith("DROP")             || biggerSQL.startsWith("DELETE")             || biggerSQL.startsWith("UPDATE")             || biggerSQL.startsWith("CREATE")             || biggerSQL.startsWith("ALTER")             || (checkArray).indexOf("DROP")>=0             || (checkArray).indexOf("DELETE")>=0             || (checkArray).indexOf("UPDATE")>=0             || (checkArray).indexOf("CREATE")>=0             || (checkArray).indexOf("ALTER")>=0             || (checkArray).indexOf("PG_")>-1  // 屏蔽系统方法            || (checkArray).indexOf("/ETC")>-1  // 屏蔽目录读取            || (checkArray).indexOf("GETPGUSERNAME")>-1             || (checkArray).indexOf("CURRENT_SCHEMA")>-1             || (checkArray).indexOf("CURRENT_USER")>-1             || (checkArray).indexOf("SYSTEM(")>-1         ){            goWrong(response, "不可执行非法查询语句:"+sql);            return;        }        let badStringList = [            "exec","execute","insert","create","drop","grant","use","group_concat","column_name","concat","pg_read_file","information_schema.columns","table_schema","delete","update","chr","mid","master","truncate","char","declare"            // ,";","--","//","/","#"        ]        if(badStringList.find(item=>checkArray.indexOf(item.toUpperCase())>-1)){            goWrong(response, "包含非法关键字:"+sql);            return;        }        if( // 限定查询操作            biggerSQL.startsWith("WITH")             || biggerSQL.startsWith("SELECT")            || biggerSQL.startsWith("(SELECT")            ){                let data = await NovaQLSELECT(sql,params);                response.json({                    code:200,                    data:data                });                return;        }else{            goWrong(response, "不可执行非法查询语句:"+sql);            return;        }    }catch(err){        goWrong(response, err.toString());        return;    }})async function NovaQLSELECT(sql,params){    return new Promise((resolve,reject)=>{        psqlDB.any(sql,params).then((data) => {            resolve(data)        })        .catch((err) => {            reject(err);        });    })}module.exports = router;
 |