症状
老胡茶室 是一个基于 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 检查来解决。