我的Web API中有一个端点,如下所示:
api/customers?salesRepId=123
现在,如果我没有在查询字符串中提供salesRepId,我希望能够吸引所有客户。如果提供了salesRepId,我想只提取销售代表的客户。
只允许管理员查看所有客户,这意味着当我以salesRepId 123身份登录并调用不带查询字符串的api / customers时,API应响应401(未经授权)错误。
如何在ASP.NET Core 2.0 Web API中执行此操作?
另一种选择是暴露2个端点,我希望避免这种情况。
答案 0 :(得分:2)
我将假设api/customers
处的控制器看起来类似于以下内容(暂时忽略返回类型):
[HttpGet("customers/{salesRepId}")]
public JsonResult Customers(int salesRepId)
而且我也会假设您以某种方式单独处理授权(可能使用属性或某些中间件)。
如果是这样,我会将salesRepId
参数改为可为空的int(here is a little about Nullable types, if you've not used them before),方法是将方法签名更改为:
[HttpGet("customers/{salesRepId}")]
public JsonResult Customers(int? salesRepId)
然后我会通过在方法中执行此操作来检查salesRepId
是否有值(即它是作为QueryString的一部分提供的):
[HttpGet("customers/{salesRepId}")]
public JsonResult Customers(int? salesRepId)
{
// userIsNotAuthorised is the name I'm giving to whatever
// whatever check you are making that the user is authorised
if (!salesRepId.HasValue && userIsNotAuthorised)
{
// return 401
}
// user is either authorised or has supplied a salesRepId or both
}
您还可以更改路由属性以匹配以下内容:
[HttpGet("customers/{salesRepId:int?}")]
public JsonResult Customers(int salesRepId = -1)
请注意,我必须在此实例中提供默认选项。这将改变我们需要更改方法体中的检查以匹配以下内容的方式:
[HttpGet("customers/{salesRepId:int?}")]
public JsonResult Customers(int salesRepId = -1)
{
// userIsNotAuthorised is the name I'm giving to whatever
// whatever check you are making that the user is authorised
if (salesRepId == -1 && userIsNotAuthorised)
{
// return 401
}
// user is either authorised or has supplied a salesRepId or both
}
我个人更喜欢尽可能使用Nullable类型。这是因为在第二个示例中,我们依赖于-1
(我们将其用作magic number,这是一种反模式。)
答案 1 :(得分:2)
除了过滤之外,您不需要salesRepId
。
当代表登录时,对api/customers
的调用应返回所有客户以及代表的所有客户。
来电api/customers?salesRepId=123
应用相同的验证(可通过policy based authentcation检查为声明或范围),但过滤结果(属于该代表的所有客户。
当管理员调用api/customers?salesRepId=123
时,他会在调用api/customers
或api/customers?salesRepId=123
时收到与销售代表相同的结果,但当销售代表调用api/customers?salesRepId=456
时,他会返回空结果(因为他的结果被456过滤了结果为空)。
或者换句话说:如果用户是某种管理用户,则控制器会将登录用户的ID设置为销售代表过滤器。
通过这种方式,您不必以不同方式处理它,并且API对每个用户的行为都相同。
不要忘记,RESTful应用程序中的查询是通过应用过滤来减少数据量的。
或者,具有到两个路线动作的路线。 api/customers
具有我上面描述的行为api/salesrepresentative/123/customers
或api/my/customers
(具体意味着它的范围缩小为登录用户)。这清楚地表明它是两种不同类型的资源。
第一个是所有客户的集合,而第二个是给定代表的所有客户。