php - PHP $_SESSION 数组在前端生产构建时为空,但在开发构建时不是
问题描述
我有一个托管在 中的后端https://api.mydomain.abc
,并且我正在使用 vue/quasar CLI 开发一个使用 webpack 服务器的前端。
当前端在开发模式下运行时,它由 webpack web 服务器托管,并且前端代码中的 url 具有/api/index.php
格式。然后将 webpack 服务器配置为将它们代理到真实的后端 url:
devServer: {
...,
proxy: {
// proxy all requests starting with /api to avoid cors problems.
'/api': {
target: 'https://api.mydomain.abc',
changeOrigin: true,
pathRewrite: {
'^/api': '' //remove /api from the final url
}
}
}
},
在生产模式下运行时,前端由 NGINX 服务器托管,https://www.mydomain.abc
前端的 url 现在直接像https://api.mydomain.abc
.
从现在开始,两种请求类型(开发和生产)都是相同的。https://api.mydomain.abc
请求由同一个 NGINX 服务器监听,但现在作为反向代理工作,将它们重定向到带有 PHP mod 的 apache 服务器。这里有一个非常简单的纯 PHP 脚本,没有任何外部框架或库,它只是管理登录并在用户正确登录时从 DB 返回一些动态值。
关键是在开发环境中一切正常,但是在生产环境中,所有受登录保护的请求都失败了,因为 $_SESSION 数组是空的!
我完全不知道是什么导致了这种错误,因为两种环境的后端都是一样的。
更多信息:
- 在 apache 服务器中设置 CORS 标头以允许来自www.mydomain.abc(以及 mydomain.abc)的请求,并且没有任何 CORS 错误。
https
两种环境都使用协议访问后端- 我的 PHP 脚本在脚本开头
session_start()
无条件运行
我已经尝试过这个答案,但没有观察到任何变化。
什么可能导致两种环境之间的这种差异?除了 webpack 服务器之外,它们实际上是相同的。
解决方案
我会自己回答。问题是,在开发过程中,浏览器位于 localhost url 中,向 localhost 服务器发出请求(webpack 服务器,然后将其代理到真正的 api 生产服务器,但浏览器不知道这一点)。这是same-origin
浏览器的环境,因此fetch
API 将凭据(phpsessioncookie)发送到服务器,因为它是环境中的默认行为same-origin
。
在生产环境中,webpack 服务器不参与其中,浏览器正在(www.)mydomain.com
对api.mydomain.com
. 这里的问题是,即使(www.)mydomain.com
在 API Web 服务器中设置为允许的来源,对于浏览器来说,它也是一个cross-origin
环境,这意味着fetch
API 默认不发送凭据。credentials:include
覆盖默认值并发送它们。
Access-Control-Allow-Credentials: "true"
如果不存在,服务器端也需要标头。
推荐阅读
- firebase - 关于 Firestore 缓存和读取费用的问题
- kubernetes - 如何在 kube 状态指标中计算 pod 的 cpu 使用率?
- r - r - 如何从样本模拟输出中找到最小化变量的参数值?
- google-chrome - 我无法在谷歌浏览器中获得 SASS 支持
- typescript - Mat单选按钮值在表单提交后没有改变
- wordpress - 我的网站网址如何成为 example.com 而不是 example.com/wordpress?
- docker - 如何加快 Gitlab CI 构建过程(不工作)
- r - 如何在时间序列上运行 ADF 测试。需要首先将系列划分为两个标准,并在一个整洁的表格中分别获得每个标准的结果
- vba - 将组合框中的值存储在文件名中
- python - 如何解决错误消息“没有名为 websocket 的模块”