Objection.js:所有 where 子句添加后是不是可以用括号括起来?
Posted
技术标签:
【中文标题】Objection.js:所有 where 子句添加后是不是可以用括号括起来?【英文标题】:Objection.js: Can all where clauses be enclosed in parentheses after they have been added?Objection.js:所有 where 子句添加后是否可以用括号括起来? 【发布时间】:2020-09-30 13:47:43 【问题描述】: 代码示例// Creates an Objection query.
// I have no control over the creation of the query. I can only modify the query after it has been created.
// Example: "select `todos`.* from `todos` where `text` = ?"
const objectionQuery = thirdPartyService.createQuery(userControlledInput);
// Adds an access check. Example "select `todos`.* from `todos` where `text` = ? and `userId` = ?"
objectionQuery.andWhere("userId", currentUser.id);
上面的例子有一个安全漏洞。如果thirdPartyService
生成这样的查询:
select `todos`.* from `todos` where `text` = ? or `id` = ?
那么在添加访问检查后我们会得到如下查询:
select `todos`.* from `todos` where `text` = ? or `id` = ? and `userId` = ?
而且这个查询可以返回不属于当前用户的数据。 要修复此错误,我们需要将用户控制的条件括在括号中:
select `todos`.* from `todos` where (`text` = ? or `id` = ?) and `userId` = ?
但是我如何使用异议查询生成器来做到这一点?我想像这样:
const objectionQuery = thirdPartyService.createQuery(userControlledInput);
wrapWhereClauses(objectionQuery);
objectionQuery.andWhere("userId", currentUser.id);
【问题讨论】:
【参考方案1】:一种方法是将原始查询包装为子查询/临时表:
MyModel.query().from(thirdPartyService.createQuery(userControlledInput)).where(...)
(请告诉我这是否有效,我还没有测试过)
【讨论】:
是的,它可以工作并创建如下查询:select * from (select
todos.* from
todos` where text
= ?) where userId
= ?`。谢谢。【参考方案2】:
来自docs:您可以通过将函数传递给任何where*
方法来为查询添加括号:
await Todo.query()
.where('userId', 1)
.where(builder =>
builder.where('text', 2).orWhere('id', 3);
);
会导致
select * from "todos" where "userId" = 1 and ("text" = 2 or "id" = 3)
【讨论】:
感谢您的回答,但我无法控制查询的创建。我只能在创建查询后修改它。所以我不能使用你的解决方案。以上是关于Objection.js:所有 where 子句添加后是不是可以用括号括起来?的主要内容,如果未能解决你的问题,请参考以下文章