routes.js 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151
  1. const router = require('express').Router();
  2. const bodyParser = require('body-parser')
  3. router.use(bodyParser.urlencoded({
  4. extended: false
  5. }));
  6. router.use(bodyParser.json({ limit: '10mb' }));
  7. // 跨域参数配置
  8. const allowCrossDomain = function (req, res, next) {
  9. res.header('Access-Control-Allow-Origin', '*');
  10. res.header('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE');
  11. res.header('Access-Control-Allow-Headers', 'Content-Type');
  12. res.header('Access-Control-Allow-Credentials', 'true');
  13. next();
  14. };
  15. router.use(allowCrossDomain)
  16. function goWrong(response,msg){
  17. response.status(500)
  18. response.json({
  19. code:500,
  20. mess:msg
  21. })
  22. return
  23. }
  24. const psqlDB = require("../../psql.service");
  25. /**
  26. * @api {post} /psql/select psql查询接口
  27. * @apiSampleRequest /api/psql/select
  28. * @apiVersion 0.5.0
  29. * @apiName psqlSELECT
  30. * @apiGroup psql
  31. * @apiParam {String} sql='SELECT * FROM "VrPanoLog" limit $1;' 仅限SQL的SELECT和WITH查询
  32. * @apiParam {String} [params='[5]' ] 参数数组
  33. * @apiSuccess {data} data 结果
  34. * @apiSuccessExample Success-Response:
  35. * HTTP/11 200 OK
  36. * {
  37. * "code": 200,
  38. * "mess": "成功",
  39. * "data": [
  40. * ]
  41. * }
  42. * @example
  43. 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]}'
  44. curl -X POST 'https://dev.fmode.cn/api/psql/select' -H 'Content-Type: application/json' --data '{"sql":"SELECT * FROM \"_User\" limit 5","params":[1]}'
  45. let response = await fetch(`https://dev.fmode.cn/api/psql/select`, {
  46. headers: {
  47. "Content-Type": "application/json"
  48. },
  49. body: JSON.stringify({"sql":"SELECT * FROM \"_User\" limit 5","params":[1]}),
  50. method: "POST",
  51. mode: "cors",
  52. credentials: "omit"
  53. });
  54. let result = await response?.json();
  55. console.log(result)
  56. */
  57. router.post('/select', async function (req, response) {
  58. // 0.接收参数,并且校验
  59. let sql = req.body.sql;
  60. let token = req.body.token;
  61. let params = req.body.params;
  62. if(!sql){
  63. goWrong(response,"缺少参数sql")
  64. return;
  65. }
  66. // 2.分析查询参数
  67. try{
  68. if(params){
  69. params = JSON.parse(params)
  70. }
  71. if(params&&params.length<1){
  72. goWrong(response,"params参数必须为数组")
  73. return;
  74. }
  75. let biggerSQL = sql.toUpperCase();
  76. let checkArray = biggerSQL.split(" ")
  77. if( // 过滤修改操作
  78. biggerSQL.startsWith("DROP")
  79. || biggerSQL.startsWith("DELETE")
  80. || biggerSQL.startsWith("UPDATE")
  81. || biggerSQL.startsWith("CREATE")
  82. || biggerSQL.startsWith("ALTER")
  83. || (checkArray).indexOf("DROP")>=0
  84. || (checkArray).indexOf("DELETE")>=0
  85. || (checkArray).indexOf("UPDATE")>=0
  86. || (checkArray).indexOf("CREATE")>=0
  87. || (checkArray).indexOf("ALTER")>=0
  88. || (checkArray).indexOf("PG_")>-1 // 屏蔽系统方法
  89. || (checkArray).indexOf("/ETC")>-1 // 屏蔽目录读取
  90. || (checkArray).indexOf("GETPGUSERNAME")>-1
  91. || (checkArray).indexOf("CURRENT_SCHEMA")>-1
  92. || (checkArray).indexOf("CURRENT_USER")>-1
  93. || (checkArray).indexOf("SYSTEM(")>-1
  94. ){
  95. goWrong(response, "不可执行非法查询语句:"+sql);
  96. return;
  97. }
  98. let badStringList = [
  99. "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"
  100. // ,";","--","//","/","#"
  101. ]
  102. if(badStringList.find(item=>checkArray.indexOf(item.toUpperCase())>-1)){
  103. goWrong(response, "包含非法关键字:"+sql);
  104. return;
  105. }
  106. if( // 限定查询操作
  107. biggerSQL.startsWith("WITH")
  108. || biggerSQL.startsWith("SELECT")
  109. || biggerSQL.startsWith("(SELECT")
  110. ){
  111. let data = await NovaQLSELECT(sql,params);
  112. response.json({
  113. code:200,
  114. data:data
  115. });
  116. return;
  117. }else{
  118. goWrong(response, "不可执行非法查询语句:"+sql);
  119. return;
  120. }
  121. }catch(err){
  122. goWrong(response, err.toString());
  123. return;
  124. }
  125. })
  126. async function NovaQLSELECT(sql,params){
  127. return new Promise((resolve,reject)=>{
  128. psqlDB.any(sql,params).then((data) => {
  129. resolve(data)
  130. })
  131. .catch((err) => {
  132. reject(err);
  133. });
  134. })
  135. }
  136. module.exports = router;