首页 > 解决方案 > 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 数组是空的!

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

更多信息:

我已经尝试过这个答案,但没有观察到任何变化。

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

标签: phpapachesessionsession-variableswebpack-dev-server

解决方案


我会自己回答。问题是,在开发过程中,浏览器位于 localhost url 中,向 localhost 服务器发出请求(webpack 服务器,然后将其代理到真正的 api 生产服务器,但浏览器不知道这一点)。这是same-origin浏览器的环境,因此fetchAPI 将凭据(phpsessioncookie)发送到服务器,因为它是环境中的默认行为same-origin

在生产环境中,webpack 服务器不参与其中,浏览器正在(www.)mydomain.comapi.mydomain.com. 这里的问题是,即使(www.)mydomain.com在 API Web 服务器中设置为允许的来源,对于浏览器来说,它也是一个cross-origin环境,这意味着fetchAPI 默认不发送凭据。credentials:include覆盖默认值并发送它们。

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


推荐阅读