1

这是一个代码设计问题:)

我有一个 DelegatingHandler 接受 http 请求标头并验证 API 密钥。我猜这是很常见的任务。在我的控制器中,我调用我的业务逻辑并传递所有与业务相关的信息。但是,现在我面临的挑战是根据某些 api 键来改变我的业务逻辑(单独的程序集)中的行为。

我想到了各种可能的解决方案......

  1. 更改业务逻辑方法签名以请求 API 密钥。

    public void SomeUseCase(Entity1 e1, Entity2 e2, string apiKey);

  2. 使用 HttpContext.Current 访问当前请求上下文。但是,我在某处读到使用 HttpContext 将我的托管选项限制为 IIS。有没有更适合的选择?

    var request = HttpContext.Current.Request; // 接下来提取头信息

  3. 使用会话(真的不想走那条路......)

你对这个话题有什么看法?

我会选择#1,尽管我不喜欢在业务逻辑方法中混入环境的东西。但是根据您的观点,您可能会认为 api-key 实际上与逻辑相关。


更新 #1: 我使用 delegatingHandler 来验证 apiKey,一旦验证,我将其添加到请求的属性集合中。

有问题的部分是“api-key”或 RegisteredIdentifier 如何传递到业务逻辑层。现在我将对象(例如 IRegisteredIdentifier)作为参数传递给业务逻辑类的构造函数。我知道没有更优雅的方法来解决这个问题(?)。我考虑过更改方法签名,但不确定是否是接口污染。有些方法需要使用 api-key,大多数不需要。经验告诉我,这个数字更有可能增长而不是下降 :) 所以在我的 bl 类中保留对它的引用似乎是一个不错的选择。

感谢您的回答 - 我认为它们都是我解决方案的一部分。我是 StackOverflow 的新手.. 但据我所知 - 我还不能评价答案。请放心,我仍然很感激:)

4

3 回答 3

1

我会建议两种不同的选择。

  • 将该值提升为自定义 HTTP 标头(例如 mycompany-api-key: XXXX 之类的东西)。这使您的委托处理程序更像一个标准的 HTTP 中介。如果您将请求移交给某个辅助内部服务器,这将非常方便。

  • 将 api-key 放入 request.Properties 字典中。Properties 字典的想法是提供一个放置有关请求的自定义元信息的地方。

HTTP 努力确保身份验证/授权与实际请求是正交的,这就是为什么我会尝试将其排除在操作签名之外的原因。

于 2013-02-13T15:05:56.967 回答
0

业务逻辑层依赖于 API 密钥。所以我建议:

interface IApiKeyProvider
{
    string ApiGet { get; }
}

..然后让您的 BLL 要求向其提供实现该接口的对象(在构造函数、设置甚至每个需要它的方法中)。

因为将来它可能不是一个 API 密钥。关键是这表明 BLL 依赖于某物,并为某物定义了合同。

真实世界的例子:

然后,在您的 DI 容器(Ninject 等)中,将您自己的 ConfigFileApiKeyProvider(或其他)实现绑定到该接口,在具有 API 密钥的“位置”(层)中。因此调用 BLL 的应用程序指定/配置 API 密钥的指定方式。

编辑:我误解了这部分是“如何通过 HTTP 做的”问题,而不是代码架构/代码设计问题。所以:

  • HTTP标头是传输方面的方式
于 2013-02-13T15:17:19.603 回答
0

我会选择选项 1。但是您可以在业务逻辑中引入实体 RegisteredIdentifier(Jim Arlow 和 Ila Neustadt 的企业模式和 MDA)。api-key 可以转换为 RegisteredIdentifier。

RegisteredIdentifier id = new RegisteredIdentitief(api-key);

public void SomeUseCase(Entity1 e1, Entity2 e2, RegisteredIdentifier id);
于 2013-02-13T08:26:29.410 回答