413RequestEntityTooLarge问题及方案详细分析
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
413RequestEntityTooLarge问题及⽅案详细分析
发现问题
由于这是前⼈写的代码,出现问题时没有太多实现逻辑和记忆可参考。
测试环境在某些时候接⼝会报错413 Request Entity Too Large, 初步观察是由于 Cookie 带有重复的授权信息导致。
导致问题的原因
同⼀个 host 的不同端⼝下有不同的应⽤创建不同的 Cookie, 当某个 API 发起请求时,会带上所有应⽤的 Cookie,导致 Cookie 长度过⼤。
进⼊⼀同个 IP 下的某端⼝登录应⽤,这时候会向浏览器写⼊ Cookie。
随着不同端⼝的应⽤越来越多,存储的 Cookie 越来越多。
当某个 API 发起请求时,会带上所有应⽤的 Cookie,导致 Cookie 长度过⼤。
达到⼀定程序时,就会触发 http 服务的 header 长度限制,导致请求失败。
浏览器演⽰
postman 演⽰
为什么开发环境没有发现此问题
不同的⼈开发不同的项⽬,不会造成多个项⽬的 Cookie 累加的情况
有 localhost/127.0.0.1/192.x.x.x 可以访问同⼀个项⽬
当正常退出时 Cookie 会被清除
疑问
Cookie 是前端写的后端写的
为什么会有这个疑问?因为都知道前后端都可以写 Cookie,并且后端可以决定是否携带 Cookie。
那么如果假设这个 Cookie 就是后端写的,那这个问题就应该由后端去解决。
从接⼝ Response 信息以及前端代码 Cookies.set 相关代码基本可以确定 Cookie 是前端写⼊的。
是否后端要求的就是当前所需的实现呢(携带其他端⼝下的 Cookie)
如果是,那么这个问题也应该由后端去解决。
根据经验,我们先假设不是。
假设依据:
存在有 Authorization/Blade-Auth 类似授权字段
不包含其他端⼝ Cookie 时系统也可正常使⽤
携带其他端⼝的 Cookie 是规范规定的,Cookie 不提供端⼝隔离
同时存在多个类似授权的 header
查看 API 的请求报⽂,可以发现以下 3 个类似授权的 header:
Authorization: xxx
Blade-Auth: xxx
Cookie: xxx
那么问题来了,这三个字段有什么不同?到底哪个是⽤于授权的?
由于存在 Authorization/Blade-Auth 字段,先假设 Cookie 是没有⽤的,或者 Cookie 只是⽤于暂存授权信息。
观察请求报⽂,Blade-Auth 中的值其实就是 Cookie 中的某⼀条⽬的值,所以如果 Blade-Auth 是授权字段,则此 Cookie 可以省略。
通过代码基本确定 Cookie 只是⽤于暂存授权信息。
PS: 当我去问后端到底是⽤哪个字段做的授权时,后端说他去看代码很⿇烦,让我前端⾃⼰去测试。
我说我可以测试出来带哪个参数⾏,哪个参数不⾏,但授权服务不是我写的,我没有保证权。
他还是拒绝告诉我这个字段。
好吧。
假设通过去除 Cookie 的⽅案,是否造成新的问题
假设去除 Cookie ,后端接⼝可以使⽤成功吗?
产⽣找到⼀个带授权的 GET 请求,居然不带任何授权字段都能通过,难道后端故意对 GET 放宽了权限?
于是我拿到了个创建助⼿的 POST 请求,同样不带任何授权字段都可以创建成功!
震惊,后端根本没授权,那要登录做什么?是不是每个应⽤都这样的?
然后我⼜换到另⼀个应⽤测试:
经测试,另⼀个应⽤需要带授权字段,且这个字段是 blade-auth,其他的 Authorization/Cookie 都可以不要,这次我就简单上个图。
另外,假设删除 Cookie,那么会影响下次 token ⾃动获取吗?会影响 token ⾃动更新逻辑吗?这⼜得进⾏⼀波代码逻辑分析……
根据 RefreshTokenKey 这个关键字,表明框架应该使⽤了 jwt 授权逻辑的过期标志获取新 token的⽅案,但搜索发现此⽅案并未落实,然后实现有可能变成在 API 调⽤后 token ⾃动续期,或者到期后⽤户需要重新登录。
但是删除 Cookie 后肯定是影响刷新页⾯后的已有 token 获取的,所以这时候要把存 Cookie 这个逻辑变为存 lcoalStore,这样存就不会带上⽆关 Cookie 了。
假设去除 Cookie ,会影响未来的功能吗?
那肯定是会的,如果将来某个接⼝需要 Cookie, 还得专门针对这个接⼝做逻辑编写不说,这个接⼝还是会出现带上其他端⼝信息的问题。
假设通过域名隔离的⽅案,是否造成新的问题
对于此⽅案,可以不修改前端任何代码,且可以使⽤ cookie 参数指定隔离情况。
仅把部署⽅式部署到不同的域名(例如使⽤⼦域名区分应⽤,⽽不是使⽤端⼝区分应⽤)即可解决问题。
前端不⽤修改的原因是:当前的 Cookie 本⾝就当授权信息存储使⽤,当更改部署⽅式之后,只是存储的键不⼀样,根据前端当前的逻辑照样可以正常读写。
理论上后端代码也不需要修改。
不过,修改之后需要发布新的可⽤链接,即需要告知使⽤的⼈员新的地址,造成⼀点沟通成本,如果要避免这个沟通成本也是可以的,对原来的地址做⼀个重定向即可。
总结
⽅案⼀:把 token 存在 store 中,⾃定义管理 token 销毁逻辑。
去除 Cookie 携带(建议后端明确给出授权字段)。
⽅案⼆:使⽤⼦域名⽅式部署应⽤。
经讨论预选:⽅案⼆。
参考。