使用 React Axios POST 请求时未设置 Express Session Cookie

Aus*_*ler 7 cookies redis express reactjs axios

设置

我已经使用 create-react-app 设置了一个前端环境。在这种环境中,我使用 Axios 向我的 Node JS Express 后端服务器 /login 端点发出 POST 请求。我使用 express-sessions 设置会话中间件并将会话存储在 Redis 中。我目前在本地主机上运行所有这些。

环境

  • React App - http://localhost:3005/kp(注意:该服务在 http://localhost:3005 上运行,但是所有路由都包含 /kp)

  • 快速后端 - http://localhost:5001

  • Redis - http://localhost:6379

什么有效

当前端向后端发送请求时,Express 服务器会执行它的操作并对用户进行身份验证;它将用户名存储在 req.session.username 中(这只是一个测试),Redis 控制台显示键值存储成功,前端网络选项卡显示 200 状态,带有 Set-Cookie 响应标头和一个选项卡显示 cookie(下面的屏幕截图)。

问题

一切似乎都运行良好,但 cookie 未在浏览器中设置。我刷新了页面,再试了很多次,但它不会在任何浏览器(谷歌 Chrome 和 Safari)中设置 cookie。我感到很沮丧,因为 Chrome 似乎承认 Set-Cookie 存在,但出于某种原因忽略了它。

我试过的

阿克西奥斯

  1. 我试过设置 withCredentials: true - 不起作用
  2. 使用 Set-Cookie 验证 cookie 在 POST 请求后被发送回前端

后端

  1. 我已经检查了我的 CORS 政策,但它们看起来很好;但是,我对 CORS 不是很好,所以那里可能存在配置错误
  2. 尝试在 CORS 策略中将凭据设置为 true
  3. 验证会话是否正在使用 Redis 设置变量。

代码

反应前端 Axios POST 请求

      axios.post('http://localhost:5001/login', loginBody, {
        headers: {
          'Content-Type': 'application/json'
        }
      },
        { withCredentials: true }
      )
        .then((res) => {
          console.log(res);
        })
        .catch((error) => {
          console.log(error);
          this.setState({
            errorMessage: `Server Error`,
            loading: false
          });
        });
Run Code Online (Sandbox Code Playgroud)

快速服务器

const express = require('express');
const http = require('http');
const cors = require('cors');
const socketServer = require('./src/sockets');
const bodyParser = require('body-parser');
const session = require('express-session');
const redis = require('redis');
const redisClient = redis.createClient();
const redisStore = require('connect-redis')(session);
process.env.NODE_TLS_REJECT_UNAUTHORIZED = "0";
const port = process.env.PORT || 5001;
const { loginRoutes } = require('./src/routers');
const app = express();

redisClient.on('error', (err) => {
  console.log('Redis error: ', err);
});

app.use(cors({
  origin: '*',
  methods: ['POST', 'PUT', 'GET', 'OPTIONS', 'HEAD'],
  credentials: true
}));

// Redis session storage setup
// API Docs for express-session: https://www.npmjs.com/package/express-session
const sessionMiddleware = session({
  secret: process.env.REDIS_SECRET || 'testing12345',
  name: 'session',
  resave: false,
  saveUninitialized: true,
  cookie: {
    secure: false
  },
  store: new redisStore(
    {
      host: process.env.REDIS_HOSTNAME,
      port: process.env.REDIS_PORT,
      client: redisClient,
      ttl: 604800
    }
  )
});

// Uses session middleware
app.use(sessionMiddleware);

app.use(bodyParser.json({ limit: '5mb' }));

const server = http.createServer(app);

// Starts Socket Server
socketServer(server, sessionMiddleware);

// Uses the routes from the router directory
app.use(loginRoutes);

server.listen(port, () => {
  console.log(`Listening on port: ${port}`);
});
Run Code Online (Sandbox Code Playgroud)

截图

网络响应

响应和请求头 Axios

请求 Cookie

响应饼干

应用程序 Cookie

应用程序 Cookie

如您所见,浏览器 cookie 列表中缺少 cookie。我有一种感觉,它很小,但我找不到任何东西。

我在任何服务中都没有收到任何错误。预先感谢您的帮助。

Aus*_*ler 8

解决方案

\n

正如 Micha\xc5\x82 Lach 指出的那样,我在 Axios 调用中将 withCredentials 放在了错误的位置。

\n

前端 Axios

\n
  axios.post(\'http://localhost:5001/login\', loginBody, {\n    headers: {\n      \'Content-Type\': \'application/json\'\n    },\n    withCredentials: true\n  })\n
Run Code Online (Sandbox Code Playgroud)\n

然而,一旦我这样做了,我就开始收到 CORS 错误。CORS 错误是您的 Access-Control-Allow-Origin(来源)配置中不能有通配符“*”。对于这个例子,我将其更改为仅指向 http://localhost:3005; 但是,有一些方法可以执行动态白名单,如下所述: https: //www.npmjs.com/package/cors#configuring-cors-w-dynamic-origin

\n

后端

\n
app.use(cors({\n  origin: \'http://localhost:3005\',\n  methods: [\'POST\', \'PUT\', \'GET\', \'OPTIONS\', \'HEAD\'],\n  credentials: true\n}));\n
Run Code Online (Sandbox Code Playgroud)\n

一旦我进行了这些更改,cookie 就开始在前端正确设置。

\n