天天看点

413 Request Entity Too Large 问题及方案详细分析

由于这是前人写的代码,出现问题时没有太多实现逻辑和记忆可参考。

测试环境在某些时候接口会报错 <code>413 Request Entity Too Large</code>, 初步观察是由于 Cookie 带有重复的授权信息导致。

同一个 host 的不同端口下有不同的应用创建不同的 Cookie, 当某个 API 发起请求时,会带上所有应用的 Cookie,导致 Cookie 长度过大。

进入一同个 IP 下的某端口登录应用,这时候会向浏览器写入 Cookie。

413 Request Entity Too Large 问题及方案详细分析

随着不同端口的应用越来越多,存储的 Cookie 越来越多。

413 Request Entity Too Large 问题及方案详细分析

当某个 API 发起请求时,会带上所有应用的 Cookie,导致 Cookie 长度过大。

413 Request Entity Too Large 问题及方案详细分析

达到一定程序时,就会触发 http 服务的 header 长度限制,导致请求失败。

浏览器演示

413 Request Entity Too Large 问题及方案详细分析

postman 演示

413 Request Entity Too Large 问题及方案详细分析

不同的人开发不同的项目,不会造成多个项目的 Cookie 累加的情况

有 localhost/127.0.0.1/192.x.x.x 可以访问同一个项目

当正常退出时 Cookie 会被清除

413 Request Entity Too Large 问题及方案详细分析

为什么会有这个疑问?因为都知道前后端都可以写 Cookie,并且后端可以决定是否携带 Cookie。那么如果假设这个 Cookie 就是后端写的,那这个问题就应该由后端去解决。

从接口 Response 信息以及前端代码 Cookies.set 相关代码基本可以确定 Cookie 是前端写入的。

如果是,那么这个问题也应该由后端去解决。

根据经验,我们先假设不是。

假设依据:

存在有 Authorization/Blade-Auth 类似授权字段

不包含其他端口 Cookie 时系统也可正常使用

携带其他端口的 Cookie 是 rfc 规范规定的,<code>Cookie 不提供端口隔离</code>

查看 API 的请求报文,可以发现以下 3 个类似授权的 header:

Authorization: xxx

Blade-Auth: xxx

Cookie: xxx

那么问题来了,这三个字段有什么不同?到底哪个是用于授权的?

由于存在 Authorization/Blade-Auth 字段,先假设 Cookie 是没有用的,或者 Cookie 只是用于暂存授权信息。

观察请求报文,Blade-Auth 中的值其实就是 Cookie 中的某一条目的值,所以如果 Blade-Auth 是授权字段,则此 Cookie 可以省略。

413 Request Entity Too Large 问题及方案详细分析

通过代码基本确定 Cookie 只是用于暂存授权信息。

413 Request Entity Too Large 问题及方案详细分析

PS: 当我去问后端到底是用哪个字段做的授权时,后端说他去看代码很麻烦,让我前端自己去测试。我说我可以测试出来带哪个参数行,哪个参数不行,但授权服务不是我写的,我没有保证权。他还是拒绝告诉我这个字段。好吧。

假设去除 Cookie ,后端接口可以使用成功吗?

产生找到一个带授权的 GET 请求,居然不带任何授权字段都能通过,难道后端故意对 GET 放宽了权限?

于是我拿到了个创建助手的 POST 请求,同样不带任何授权字段都可以创建成功!

413 Request Entity Too Large 问题及方案详细分析

震惊,后端根本没授权,那要登录做什么?是不是每个应用都这样的?

然后我又换到另一个应用测试:

经测试,另一个应用需要带授权字段,且这个字段是 blade-auth,其他的 Authorization/Cookie 都可以不要,这次我就简单上个图。

413 Request Entity Too Large 问题及方案详细分析

另外,假设删除 Cookie,那么会影响下次 token 自动获取吗?会影响 token 自动更新逻辑吗?这又得进行一波代码逻辑分析……

413 Request Entity Too Large 问题及方案详细分析

根据 RefreshTokenKey 这个关键字,表明框架应该使用了 jwt 授权逻辑的 <code>过期标志获取新 token</code> 的方案,但搜索发现此方案并未落实,然后实现有可能变成在 API 调用后 token 自动续期,或者到期后用户需要重新登录。

但是删除 Cookie 后肯定是影响刷新页面后的已有 token 获取的,所以这时候要把存 Cookie 这个逻辑变为存 lcoalStore,这样存就不会带上无关 Cookie 了。

根据分析和论证,预计方案为把 token 存在 store 中,自定义管理 token 销毁逻辑。

去除 Cookie 携带(建议后端明确给出授权字段)。

可见一些问题的出现,通常人们都只愿意在前端去发现它,并且让前端去处理,几乎没有人会去关注后端的实现情况、质量情况。

继续阅读