PHP $_SESSION 数组在前端生产构建中为空,但在开发构建中不存在

PHP $_SESSION array is empty with frontend production build but NOT with developement build

我在 https://api.mydomain.abc 中托管了一个后端,并且我正在使用 vue/quasar CLI 开发一个使用 webpack 服务器的前端。

当前端是 运行 开发时 mode 它由 webpack web 服务器托管,前端代码中的 urls 具有 /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
      }
    }
  }
},

当 运行 在生产中时 mode 前端由位于 https://www.mydomain.abc 的 NGINX 服务器托管,前端中的 urls 现在直接像 https://api.mydomain.abc.

从现在开始,两种请求类型(开发和生产)都相同。 https://api.mydomain.abc 请求由同一个 NGINX 服务器侦听,但现在作为反向代理工作,将它们重定向到具有 PHP mod 的 apache 服务器。这里有一个非常简单的普通 PHP 脚本,没有任何外部框架或库,它只管理登录和 return 如果用户正确登录,来自数据库的一些动态值。

重点是在开发环境中一切正常,但在生产环境中所有登录保护请求都会失败,因为 $_SESSION 数组为空!!

我完全不知道是什么导致了这类错误,因为两种环境的后端都是一样的。

更多信息:

我已经尝试 this answer 但没有发现任何变化。

是什么导致了两种环境之间的差异?除了 webpack 服务器之外,它们实际上是相同的。

我会自己回答。问题是在开发过程中,浏览器在本地主机 url 中,向本地主机服务器(webpack 服务器,然后将其代理到真正的 api 生产服务器,但浏览器没有意识到这一点).这是浏览器的 same-origin 环境,因此 fetch API 将凭据 (phpsessioncookie) 发送到服务器,因为这是 same-origin 环境中的默认行为。

在生产环境中,webpack 服务器未参与其中,浏览器在 (www.)mydomain.com 中向 api.mydomain.com 发出请求。这里的问题是,即使 (www.)mydomain.com 在 API 网络服务器中被设置为允许的来源,对于浏览器来说它是一个 cross-origin 环境,这意味着 fetch API 默认情况下不发送凭据。 credentials:include 覆盖默认值并发送它们。

如果 header Access-Control-Allow-Credentials: "true" 不存在,服务器端也需要它。