即使使用withCredential:true

时间:2018-10-27 07:06:08

标签: node.js reactjs cookies cors axios

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

    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(反应)

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时,一切正常。知道我的代码有什么问题吗?

5 个答案:

答案 0 :(得分:1)

我弄清楚了我的错误。将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);
   })

我仍然想问为什么这个改变有帮助,所以任何答案都会受到赞赏

答案 1 :(得分:1)

如果您打算多次使用,则只需创建一个axios配置:

client / 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 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;

client / 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标头,而只需在定义express中间件的任何地方使用cors

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

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

答案 2 :(得分:0)

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
}));

答案 3 :(得分:0)

我发现这篇文章很有帮助:https://medium.com/acmvit/handling-cookies-with-axios-872790241a9b

但是可能取决于服务器设置。

在客户端设置的Axios标头:

headers: {Authorization: `Bearer ${cookie_value}`},
withCredentials: true,
crossDomain: true

答案 4 :(得分:0)

现在2020年,Chrome会为跨域Cookie设置添加更多烦人的限制,您必须将SameSite设置为none来设置cookie,否则Chrome将拒绝发送cookie。此外,如果您设置SameSite,则必须设置secure

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

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