即使使用 withCredential: true,axios 也无法通过请求发送 cookie

IT技术 node.js reactjs cookies cors axios
2021-05-25 16:14:48

我已经在这样的服务器上设置了

    app.use((req, res, next) => {
  res.header('Access-Control-Allow-Origin', 'http://localhost:3000');
  res.header(
    'Access-Control-Allow-Headers', 'Origin, X-Requested-With, Content-Type, Accept, Authorization,  X-PINGOTHER'
  );
  res.header('Access-Control-Allow-Credentials', true);
  res.header('Access-Control-Allow-Methods', 'GET, POST, PUT, PATCH, DELETE, HEAD, OPTIONS');
  next();
});

和客户端的 axios (react) 像这样

axios.defaults.withCredentials = true;
axios('http://127.0.0.1:3001/orders', {
  method: 'GET',
  withCredentials: true
}).then(res => {
     console.log(res);
   }).catch(err => {
     console.log(err.response);
   })

当我用 Postman 测试并直接输入 chrome 时,一切正常。知道我的代码有什么问题吗?

4个回答

如果你打算多次使用这个,那么只需创建一个 axios 配置:

客户端/src/utils/axiosConfig.js

import axios from 'axios';

const baseURL = process.env.NODE_ENV === "development"
  ? "http://localhost:3001/"
  : "http://example.com"

const app = axios.create({
    baseURL,
    withCredentials: true
})

/* 
  The below is required if you want your API to return 
  server message errors. Otherwise, you'll just get 
  generic status errors.

  If you use the interceptor below, then make sure you 
  return an "err" (or whatever you decide to name it) message 
  from your express route: 
  
  res.status(404).json({ err: "You are not authorized to do that." })

*/
app.interceptors.response.use(
  response => (response), 
  error => (Promise.reject(error.response.data.err))
)

export default app;

客户端/src/actions/exampleAction.js

import app from '../utils/axiosConfig';

export const exampleAction = () => (
  app.get('orders') // this will be defined as baseURL + "orders" (http://localhost:3001/orders)
    .then(res => console.log(res))
    .catch(err => console.log(err))
)

然后对于您的 API,您可以简单地在定义中间件的任何地方使用cors,而不是指定 CORS 标头express

const cors = require('cors');
const origin = process.env.NODE_ENV === "development" 
  ? "http://localhost:3000" 
  : "http://example.com"

app.use(
  cors({
    credentials: true,
    origin
  }),
);

现在 2020 年,Chrome 对跨域 cookie 设置添加了更多恼人的限制,您必须将 cookie 设置SameSitenone,否则 Chrome 将拒绝发送 cookie。另外,如果设置了 SameSite,则必须设置secure.

下面是如何在 nginx 中设置此更改的示例,它可能不适用于您的情况,但仅供参考。

proxy_cookie_path / "/; secure; SameSite=none";

我弄清楚我的错误。将 axios 代码更改为

axios.defaults.withCredentials = true;
axios('http://localhost:3001/orders', {
  method: 'GET',
  withCredentials: true
}).then(res => {
     console.log(res);
   }).catch(err => {
     console.log(err.response);
   })

我仍然想问为什么这个改变有帮助所以任何答案都将不胜感激

axios.post('http://localhost:5000/api/auth/login',{ userEmail, userPassword },{
        withCredentials: true,
      })


const cors = require("cors");
expressApplication.use(cors({
 origin: ["http://localhost:2000", "http://localhost:3000"],
 credentials: true
}));