API网关排序查询字符串

时间:2017-11-21 13:40:59

标签: node.js express aws-lambda aws-api-gateway serverless-framework

我目前正在尝试使用API​​ Gateway + Lambda上的无服务器框架实现Express应用程序。在我开始介绍请求签名之前,一切都按预期工作。签名的工作方式是使用秘密令牌签署包括查询字符串在内的完整URL。不幸的是,似乎API网关或Cloudfront按字母顺序重新排序查询字符串,这导致我们生成的校验和与客户端生成的校验和不同。

我们的Express服务器看到了什么:

https://example.com/endpoint?build_number=1&platform=ios

客户发送的内容:

https://example.com/endpoint?platform=ios &build_number=1

正如您所看到的,查询参数按字母顺序重新排序,这不是我期望的行为。

有什么想法吗?

1 个答案:

答案 0 :(得分:1)

我建议您的算法注定会给您带来问题,因为查询字符串是一组没有内在排序的键/值对。

不应期望它以任何特定顺序通过任何特定系统。请求标头也是如此。一些构建HTTP请求的库将查询字符串参数存储在一个中间字典/哈希结构中,所以即使没有你在这里看到的问题(我怀疑它是API网关,因为CloudFront claims保留了排序),这是可以说是次优设计,因为?color=red&size=large(再次,可以说,但非常引人注目) - 完全?size=large&color=red相同。

我的猜测是,API Gateway可能会通过规范化查询字符串排序来优化其执行缓存的能力(实际上并不使用CloudFront缓存 - 它有自己的实现)。

但是,正如我上面所建议的那样,你的算法应该要求发送端的查询参数采用二进制,词法排序(区分大小写,而不是"字母顺序"可能假设不区分大小写)接收端也是如此。

这似乎是不必要的复杂性,但这几乎可以肯定为什么各种AWS签名算法需要查询字符串(和标题,出于同样的原因)键和值在签名之前进行排序 - 因为你根本无法做到依赖客户端库,代理或其他实体来一致地处理它们。