老胡茶室
老胡茶室

排错:Astro 部署 Vercel 环境发起 POST 请求遇到 403 错误


症状

老胡茶室 是一个基于 Astro 的带 AI 增强的知识门户,部署在 Vercel 上。

最近我们发现用户在支付成功之后,支付宝的回调请求总是 403 错误。于是我们用 curl 模拟了一下这个请求,发现确实如此:

curl -v -XPOST -H "Content-Type: application/x-www-form-urlencoded" -d "a=1&b=2&c=3" https://www.dteam.top/api/.../callback
#...
Cross-site POST form submissions are forbidden

最终返回了 403 错误,并且提示了 Cross-site POST form submissions are forbidden这个错误信息,而这个错误信息是在本地开发环境从未见过的。

分析

经过一番研究,我们发现这个问题是由于 Astro 的安全策略导致的。Astro 在处理跨站点 POST 请求时,默认会阻止来自其他域的 POST 表单提交,以防止 CSRF 攻击。

而官方 issue 也有人提到这个问题: withastro/astro#12851

考虑到这个问题也跟我们之前遇到的问题一模一样: 排错:Vercel Preview 环境下 Better Auth 登录 invalid origin 问题,应该是 Vercel 在自定义域名的环境下,并没有注入正确的 Origin 信息,导致 Astro 误判了请求的来源。

解决方案

astro 配置中提到了一个 security.checkOrigin 配置项,可以用来控制是否检查请求的 Origin。

security: {
  checkOrigin: false;
}

于是在 astro.config.mjs 中添加了这个配置,问题解决。astro 本身似乎并没有提供像 better auth 那样的 trustedOrigins 配置项,所以只能通过关闭 Origin 检查来解决。