后端要求前端传的查询参数
比如,你输入一个手机号,进行查询,要把你手机号的值,查询是 like 还是=,数据是 string 还是 int,模糊还是精准查询,全部前端拼给后端。。。
这种方案可行吗。。。
比如,你输入一个手机号,进行查询,要把你手机号的值,查询是 like 还是=,数据是 string 还是 int,模糊还是精准查询,全部前端拼给后端。。。
这种方案可行吗。。。
关注一下防注入就行
不过虽然是可行, 方案不合理啊, 前端关心的是”模糊查询”而不是”模糊查询用 like”
前端就要把查询参数封装成上面那种数组
如果有注入风险,请大佬们马上提醒我。
@zycojamie #13 我觉得这么做挺好的,没问题
假如一些业务系统就是很需要很精确的查询:比较、类别、模糊 /精确切换等你怎么做???
现在后端要求是前端把这些非常精细的条件传过去,后端翻译成 sql,又没让前端直接拼、传 sql,只要后端在生成 sql 的时候做好防注入,有什么问题?
有好事者试着传了个 DROP TABLE xxx,然后就没有然后了
// Base Model
/**
* 根据 filter 构建查询条件.
*
* @param array|null $filterList
* @param array $filterFieldMapDbField
* @return array
*/
public static function buildWhereMap($filterList, array $filterFieldMapDbField =
[]): array
{
$filterFieldMapDbField = empty($filterFieldMapDbField) ? static::FILTER_FIELD_MAP_DB_FIELD : $filterFieldMapDbField;
$map = [];
if ( !is_array($filterList) ) {
return [];
}
foreach ($filterList as $filterField => $item) {
if ( $item instanceof Closure ) {
$map[] = $item;
continue;
}
if ( !is_array($item) || !array_key_exists(‘condition’, $item)
|| !array_key_exists(‘val’, $item) ) {
continue;
}
if ( $item[‘val’] === ” || $item[‘condition’] === Condition::TYPE[‘undefined’] ||
!in_array($item[‘condition’], Condition::TYPE, true)
) {
continue;
}
if ( !array_key_exists($filterField, $filterFieldMapDbField) ) {
continue;
}
$dbField = $filterFieldMapDbField[$filterField];
$condition = Condition::DB_CONDITION[$item[‘condition’]];
$map[] = [
$dbField, $condition, Condition::formatVal($item[‘condition’], $item[‘val’]),
];
}
return $map;
}
“`
前端代码:
“`typescript
// 一个模型只需要定义下面这些 就可以使用通用增删改查 5 个接口了
type Model = Expert
const route = ‘/expert’
type FilterKeys =
| ‘id’
| ‘ctime’
| ‘expertCode’
| ‘name’
| ‘userName’
| ‘departmentId’
| ‘orgCode’
| ‘orgName’
| ‘provCode’
| ‘cityCode’
| ‘countyCode’
| ‘provName’
| ‘cityName’
| ‘countyName’
| ‘level’
| ‘intro’
| ‘type’
| ‘mobile’
| ‘phone’
| ’email’
| ‘qq’
| ‘wx’
| ‘remark’
| ‘serviceType’
type OrderKeys = ‘id’ | ‘ctime’
type Scene = ‘admin’ | ‘default’
interface QueryExtra extends BaseExtra<Scene> {}
type ActGetListParam = GetListParam<FilterKeys, OrderKeys, QueryExtra>
type AddData = Omit<Model, ‘adeptLabelList’ | ‘department’ | ‘id’>
type EditData = AddData & Pick<Model, ‘id’>
export async function lists<T = Model>(data: ActGetListParam) {
return bpost<{ list: T[] }>({
url: route + ‘/list’,
data,
})
}
“`
qset = model.objects.using(using_database).all()
if filters:
# print(‘筛选条件:’,filters)
qset = filterHelper(filters, qset)
if sorts:
# print(‘排序条件:’,sorts)
qset = qset.order_by(*sorts.split(‘,’))
if is_distinct == ‘yes’:
qset = qset.distinct()
all_num = qset.count() # 总个数
qset = qset[start_num: start_num + get_num]
if want_fileds:
data_list = createSerializers(model, want_fileds.split(‘,’))(qset, many=True).data
else:
data_list = Ser_L(qset, many=True).data
data = {‘all_num’: all_num, ‘data_list’: data_list}
应该是这个意思吧?
只要不是由前端拼接 SQL,这没啥问题啊
// 过滤条件
// 过滤条件按需使用,没有过滤条件就不传 filter
“filter”: {
// and 表示 “且”,也支持 or,但是实际业务用的比较少而且性能不佳 or 不建议使用
“and”: [
// like 条件
{“mobile”: {“like”: “1”}},
// level = 1
{“level”: 1},
// 范围条件 id in [2, 5, 9]
{“id”: {“in”: [2, 5, 9]}},
// createdAt > 0
{“createdAt”: {“gt”:0}},
// createdAt < 10000000000
{“createdAt”: {“lt”:10000000000}}
]
}
// 每页记录数,后端默认 10 条
“perPage”: 10,
// 请求页数
“page”: 1,
// 排序值,优先级从前到后“-”表示倒序
“sort”: “-isDefault,-isCertified,-id”
}