😎1、优化仓储扩展可能引发sql注入问题 2、优化接口压测页面

This commit is contained in:
zuohuaijun 2025-06-27 01:29:49 +08:00
parent d8b7584095
commit f18585d5e9
2 changed files with 21 additions and 14 deletions

View File

@ -145,12 +145,12 @@ public static class RepositoryExtension
typeAdapterConfig.ForType<T, BasePageInput>().IgnoreNullValues(true);
Mapper mapper = new(typeAdapterConfig); // 务必将mapper设为单实例
var nowPagerInput = mapper.Map<BasePageInput>(pageInput);
// 排序是否可用-排序字段和排序顺序都为非空才启用排序
if (!string.IsNullOrEmpty(nowPagerInput.Field) && !string.IsNullOrEmpty(nowPagerInput.Order))
// 排序是否可用-排序字段为非空才启用排序,排序顺序默认为倒
if (!string.IsNullOrEmpty(nowPagerInput.Field))
{
var col = queryable.Context.EntityMaintenance.GetEntityInfo<T>().Columns.FirstOrDefault(u => u.PropertyName.Equals(nowPagerInput.Field, StringComparison.CurrentCultureIgnoreCase));
var dbColumnName = col != null ? col.DbColumnName : nowPagerInput.Field;
orderStr = $"{prefix}{iSqlBuilder.GetTranslationColumnName(dbColumnName)} {(nowPagerInput.Order == nowPagerInput.DescStr ? "Desc" : "Asc")}";
nowPagerInput.Field = Regex.Replace(nowPagerInput.Field, @"[\s;()\-'@=/%]", ""); //过滤掉一些关键字符防止构造特殊SQL语句注入
var orderByDbName = queryable.Context.EntityMaintenance.GetDbColumnName<T>(nowPagerInput.Field);//防止注入,类中只要不存在属性名就会报错
orderStr = $"{prefix}{iSqlBuilder.GetTranslationColumnName(orderByDbName)} {(string.IsNullOrEmpty(nowPagerInput.Order) || nowPagerInput.Order.Equals(nowPagerInput.DescStr, StringComparison.OrdinalIgnoreCase) ? "Desc" : "Asc")}";
}
return queryable.OrderByIF(!string.IsNullOrWhiteSpace(orderStr), orderStr);
}

View File

@ -166,13 +166,20 @@ onMounted(async () => {
//
const getApiGroupList = async () => {
try {
const html = await request(`/index.html`, { method: 'get' }).then(({ data }) => data);
const prefixText = "var configObject = JSON.parse('";
const jsonStr = html
.substring(html.indexOf(prefixText) + prefixText.length, html.indexOf('var oauthConfigObject = JSON.parse('))
?.trim()
.replace("');", '');
return JSON.parse(jsonStr).urls;
const response = await request('/swagger-resources', { method: 'get' });
return response.data
.filter((resource: { name: string; url: string }) => !resource.url.toLowerCase().includes('all%20groups'))
.map((resource: { name: string; url: string }) => {
const rawUrl = resource.url || '';
let fixedUrl = rawUrl.startsWith('//') ? rawUrl.substring(1) : rawUrl;
if (!fixedUrl.startsWith('/') && !fixedUrl.includes('://')) {
fixedUrl = '/' + fixedUrl;
}
return {
name: decodeURIComponent(resource.name || ''),
url: fixedUrl,
};
});
} catch {
return [];
}
@ -181,10 +188,10 @@ const getApiGroupList = async () => {
//
const getApiList = (keywords: string | undefined) => {
const emojiPattern =
/[\u{1F600}-\u{1F64F}\u{1F300}-\u{1F5FF}\u{1F680}-\u{1F6FF}\u{1F700}-\u{1F77F}\u{1F780}-\u{1F7FF}\u{1F800}-\u{1F8FF}\u{1F900}-\u{1F9FF}\u{1FA00}-\u{1FA6F}\u{1FA70}-\u{1FAFF}\u{2600}-\u{26FF}\u{2700}-\u{27BF}]/gu;
/[\u{2139}\u{2B05}-\u{2B07}\u{1F600}-\u{1F64F}\u{1F300}-\u{1F5FF}\u{1F680}-\u{1F6FF}\u{1F700}-\u{1F77F}\u{1F780}-\u{1F7FF}\u{1F800}-\u{1F8FF}\u{1F900}-\u{1F9FF}\u{1FA00}-\u{1FA6F}\u{1FA70}-\u{1FAFF}\u{2600}-\u{26FF}\u{2700}-\u{27BF}]/gu;
return request(state.swaggerUrl, { method: 'get' }).then(({ data }) => {
const pathMap = data.paths;
const result = data.tags.map((e: any) => ({ path: e.name, summary: e.description.replaceAll(emojiPattern, ''), children: [] }));
const result = data.tags.map((e: any) => ({ path: e.name, summary: e.description?.replaceAll(emojiPattern, '') || e.name, children: [] }));
Object.keys(pathMap).map((path) => {
const method = Object.keys(pathMap[path])[0];
const apiInfo = pathMap[path][method];