使用 AFNetworking 2.0 签署 API 请求

Posted

技术标签:

【中文标题】使用 AFNetworking 2.0 签署 API 请求【英文标题】:Signing API requests using AFNetworking 2.0 【发布时间】:2014-02-20 00:49:50 【问题描述】:

所以我使用 AFNetworking 来使用 API。

此 API 要求使用 hmac 对所有请求进行签名。 hmac 是根据 headers、url 和 body 的组合计算的。然后将 hmac 作为自定义标头添加到请求中。

计算 hmac 并将其添加到标题中不是问题。但是,似乎在处理请求之前“在最后一分钟”添加了一些标头。

我的 API 客户端是 AFHTTPSessionManager 的子类,我一直在寻找进行签名的最佳位置,目前正在通过重载来实现:

- (NSURLSessionDataTask *)dataTaskWithRequest:(NSURLRequest *)request
                          completionHandler:(void (^)(NSURLResponse *response, id responseObject, NSError *error))completionHandler

当我在测试 API 服务器上模拟请求以查看我收到的标头时,总是有 2 个附加标头在我签署请求时不存在:Accept-EncodingConnection,有时我也会得到Cookie 标头。

除了 hmac 签名之外,我自己添加的唯一标头是 AcceptContent-Type 以及特定于 APIi 的自定义标头,指示我的客户密钥。

所以我的问题是,签署此协议的最佳方式/地点是什么?

【问题讨论】:

【参考方案1】:

AFNetworking 没有添加这些标头,NSURLSession 是(如果您切换到 AFHTTPRequestOperationManager 则 NSURLConnection 会添加)。

从技术上讲,覆盖的“正确”方法是您的请求序列化程序子类上的 requestWithMethod: URLString: parameters: error:,而不是您的 AFHTTPSessionManager。但这不会解决您的问题,因为 AFNetworking 不是添加这些标题的人。 (您当前的方法也很好,如果您需要为不同的 URL 提供不同的行为,则灵活性会降低)。

您可能的解决方案是(在我看来,从最好到最差排序):

    将您的 API 更改为不使用 hmac 中的标头,或者根本不使用此 hmac(此 hmac 是否为您提供 HTTPS 和 SSL Pinning 没有的任何功能?) 在您的请求序列化程序/会话管理器子类中手动设置这些标头(我不认为 NSURL[Session|Connection] 会覆盖它们)。有很多缺点;例如,您必须使用 NSHTTPCookieStorage 自己管理 cookie 存储。您还必须希望获得所有这些,因为 Apple 的文档没有说明它们在哪些情况下添加了哪些标头。 完全移除 AFNetworking 和 NSURL[Session|Connection],并将其替换为基于较低级别 CFNetwork 框架的内容(long-abandoned ASIHTTPRequest library 可能是您最好的选择。)

编辑:另一种想法 - 您可以尝试在您的 AFHTTPSessionManager 上调用 setTaskWillPerformHTTPRedirectionBlock:。此时可能会添加 HTTP 标头,因此您可以在那里重新计算 hmac。 (我没有对此进行测试;请告诉我这是如何工作的。)

【讨论】:

感谢您的反馈,不幸的是选项 1 不是一个选项,我必须使用这个 API,这是在他们的沙盒环境之外使用它的要求。我一定会试一试选项 2 并就此与您联系。关于选项 3,如果该项目已被放弃,我宁愿暂时避免它。

以上是关于使用 AFNetworking 2.0 签署 API 请求的主要内容,如果未能解决你的问题,请参考以下文章

AfNetworking 2.0 发布问题

AFNetworking 2.0 - 是不是使用子类?

AFNetworking 2.0,使用 NSURLSession 下载图片

使用 AFNetworking 2.0 加载图像

使用 AFNetworking 2.0 异常解析 JSON

使用 afnetworking 2.0 发送字典数组