基于请求体mailTo的Azure APIM速率限制策略调用报错排查
解决Azure APIM基于请求体属性限流时返回400错误的问题
问题场景
配置了Azure APIM的rate-limit-by-key策略,基于请求体中的mailTo属性实现速率限制,策略代码如下:
<rate-limit-by-key calls="5" renewal-period="10" counter-key="@(context.Request.Body.As<JObject>()["mailTo"].ToString())" />
请求体示例:
{ "mailTo": "myemail@gmail.com" }
直接调用后端服务正常,但通过APIM调用时返回400错误,错误信息:
{ "errors": { "": [ "A non-empty request body is required." ] }, "type": "https://tools.ietf.org/html/rfc7231#section-6.5.1", "title": "One or more validation errors occurred.", "status": 400, "traceId": "00-......-3be881755d918044-00" }
问题原因
APIM中调用context.Request.Body.As<JObject>()方法时,默认会一次性读取请求体流并将流指针移至末尾,后续后端服务尝试读取请求体时,会得到空内容,触发后端的“非空请求体必填”验证错误。
解决方案
修改策略代码,在读取请求体时添加preserveContent: true参数,确保读取后请求体流的指针重置,后端服务能正常获取请求体内容:
<rate-limit-by-key calls="5" renewal-period="10" counter-key="@(context.Request.Body.As<JObject>(preserveContent: true)["mailTo"].ToString())" />
也可以分步骤处理,先将请求体缓存到变量中再使用,同样保留请求体内容:
<set-variable name="requestBody" value="@(context.Request.Body.As<JObject>(preserveContent: true))" /> <rate-limit-by-key calls="5" renewal-period="10" counter-key="@(((JObject)context.Variables["requestBody"])["mailTo"].ToString())" />
内容的提问来源于stack exchange,提问作者Alpesh
相关产品推荐
相关产品推荐

