HTTP状态代码-401/NotAuthorized vs 404/NotFound vs 400/BadRequest



我有属于公司实体的Widget实体。Companies和Widgets之间存在一对多关系。

这是我第一次通过Get方法:

[Route("MyApi/Companies/{companyId}/WidgetAdministration/[controller]")]
[HttpGet("{widgetId}")]
public async Task<ActionResult<WidgetDTO>> GetWidget([FromRoute] int companyId, [FromRoute]int widgetId)
{
WidgetDTO widgetDto = await _myContext.Widgets
.Where(w => w.CompanyId == companyId && w.WidgetId == widgetId)
.AsNoTracking()
.ProjectTo<WidgetDTO>(_mapper.ConfigurationProvider)
.FirstOrDefaultAsync();
if (widgetDto == null)
{
return NotFound();
}
else
{
return Ok(widgetDto);
}
}

如果与"公司1"关联的用户请求"公司1 Widget 55",但"Widget 55"属于"公司2",我应该返回什么?

404/NotFound-由于"Widget 55"属于"Company 2",即使"Widget五十五"确实存在,上述LINQ语句也找不到任何东西。

401/NotAuthorized-由于"Widget 55"不属于"Company 1","Company 1"无权查看。

400/BadRequest-这只是一个糟糕的请求,因为Widget和Company不匹配。

顺便说一句,有人能推荐一个好的资源来帮助我处理其他类似的场景吗?

我会返回404,原因有两个:

  1. 在我看来,404不是指Widget/55,而是指整个资源URI:Company/1/Widget/55。此资源不存在
  2. 403阻止公司1查看公司2的小部件,但它确实暴露了Widget/55存在的事实。你可能会接受,也可能不会接受。根据万维网联盟(W3C(的说法,"如果服务器不希望向客户端提供这些信息,则可以使用状态代码404(未找到(。">

如果您使用403,您将泄露安全信息,因为我们声明资源存在,但您无法查看它,从而验证资源的存在。

请在此处阅读有关混淆HTTP状态代码的更多信息。