c# - 防止 API 调用中的意外删除

标签 c# asp.net rest asp.net-web-api

我有一个网络方法来删除家具或他的一个属性:

[Authorize]
[Route("api/furniture/{furnitureId}/{property?}")]
public HttpResponseMessage Delete(string furnitureId, string property = null)
{
    try
    {
        if (property != null)
            _furnitureService.DeleteFurnitureProperty(furnitureId, property);
        else
            _furnitureService.DeleteFurniture(furnitureId);
    }
    catch (Exception ex)
    {
        return Request.CreateErrorResponse(HttpStatusCode.BadRequest, ex.Message);
    }
    return Request.CreateResponse(HttpStatusCode.Accepted);
}

当进行适当的调用时,它按预期工作:

  • /api/furniture/id01 - 删除家具 id01
  • /api/furniture/id01/p001 - 删除家具 id01 上的属性 p001
  • /api/furniture/id01?property=p001 - 也删除属性 p001 家具 id01

但由于 API 使用不当,我收到了一些投诉。 例如,以下调用将删除家具:

  • /api/furniture/id01?prop=p001

请注意,它使用了错误的 prop 参数名称,而不是 property

我知道他们有调用错误,但是删除家具有一些影响,需要我这边预防(它也可以恢复,但需要消费者更多的步骤)

所以,我的问题是:当调用者使用允许的参数以外的任何其他参数时,我能否轻松检测和限制?这样我就可以返回 400 错误而不是删除家具。 如果没有直接的方法,请推荐更简单的方法(比如Request.Params object regex?)

最佳答案

编辑: 基于这是在生产中的事实,我建议创建如下所示的 ActionFilterAttribute:

public class ValidateQueryParametersFilterAttribute : ActionFilterAttribute
{
    private IEnumerable<string> _validQueryParameters;

    public ValidateQueryParametersFilterAttribute(params string[] validQueryParameters)
    {
        if (validQueryParameters != null)
        {
            _validQueryParameters = validQueryParameters.Where(x => !string.IsNullOrWhiteSpace(x));
        }
    }

    public override Task OnActionExecutingAsync(HttpActionContext actionContext, CancellationToken cancellationToken)
    {
        if (actionContext.Request.GetQueryNameValuePairs().Any(x => !_validQueryParameters.Contains(x.Key)))
        {
            actionContext.Response = actionContext.Request.CreateErrorResponse(HttpStatusCode.BadRequest, "You sent me an invalid property.");
        }
        return base.OnActionExecutingAsync(actionContext, cancellationToken);
    }
}

如果您不喜欢使用参数,则可以使用逗号分隔的字符串。许多框架使用逗号分隔的字符串而不是参数。事实上,根据您的规则,您可能会在发布时收到构建错误。为简单起见,我只做了参数。

然后像这样将它应用到 Controller :

[ValidateQueryParametersFilter("property")]
[Route("api/furniture/{furnitureId}/{property?}")]
public async Task<HttpResponseMessage> Delete([FromUri] string furnitureId, string property = null)
{
            
    return Request.CreateResponse(HttpStatusCode.Accepted);
}

最佳答案是避免这种类型的路由。我会在您的 API 的 future 版本中将您的路由调整为以下内容:

[Route("api/furniture/{furnitureId}/properties/{propertyId}")]

此外,我强烈建议使用 FromRouteFromQuery 属性。您的 Controller 更改为:

[Authorize]
[Route("api/furniture/{furnitureId}/properties/{propertyId}")]
public HttpResponseMessage Delete([FromRoute] string furnitureId, [FromRoute] string property)
{
    //...
}

这使得关系更加清晰。另外,你可以看看 https://www.nuget.org/packages/JsonPatch/用于在资源上执行补丁。

关于c# - 防止 API 调用中的意外删除,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46957941/

相关文章:

c# - 列出 Foreach 参数化委托(delegate)

c# - 读取包含希腊字符的 CSV 文件

c# - 将访问 token 传递到 Azure 服务管理 (REST) 时被禁止

java - 一个 URI 模板形式的路径变量数量不受限制

java - 连接到 PHP 的 RESTful Java 应用程序

c# - 分组/嵌套 ListView

c# - 拆分字符串值并存储在列表中

c# 屏幕抓取并获取所有 cookie 以安全访问网站

javascript - javascript 中的 ASP.NET Core ViewData 访问

javascript - 将隐藏字段值传递给 javascript (href)