让Axios在请求中自动发送cookie

我正在使用Axios从客户端向Express.js服务器发送请求。

我在客户机上设置了一个cookie,我希望从所有Axios请求中读取该cookie,而不需要手动将它们添加到请求中。

这是我的客户端请求示例:

axios.get(`some api url`).then(response => ...

我试图通过在Express.js服务器中使用这些属性来访问头文件或cookie:

req.headers
req.cookies

它们都没有包含任何cookie。我使用cookie解析器中间件:

app.use(cookieParser())

如何让Axios在请求中自动发送cookie ?

编辑:

我在客户端设置cookie是这样的:

import cookieClient from 'react-cookie'


...
let cookie = cookieClient.load('cookie-name')
if(cookie === undefined){
axios.get('path/to/my/cookie/api').then(response => {
if(response.status == 200){
cookieClient.save('cookie-name', response.data, {path:'/'})
}
})
}
...

虽然它也使用Axios,但它与问题无关。我只是想在设置cookie后将cookie嵌入到所有请求中。

485896 次浏览

你可以使用withCredentials属性。

来自不同域的XMLHttpRequest不能为自己的域设置cookie值,除非在发出请求之前将withCredentials设置为true。

axios.get(BASE_URL + '/todos', { withCredentials: true });

此外,还可以对每个Axios请求强制凭据

axios.defaults.withCredentials = true

或者对某些Axios请求使用凭据,如下面的代码所示

const instance = axios.create({
withCredentials: true,
baseURL: BASE_URL
})
instance.get('/todos')

你把两种想法混在一起了。

有react-cookie和axios

React-cookie =>用于在客户端处理cookie

Axios =>用于向服务器发送ajax请求

有了这些信息,如果您希望来自客户端的cookie也能在后端进行通信,则需要将它们连接在一起。

来自"react-cookie" Readme的注释:

同构饼干!

要在执行服务器呈现时能够访问用户cookie,您需要 可以使用plugToRequest或setRawCookie

link to readme

如果这是你需要的,很好。

如果没有,请评论,以便我可以详细说明。

我不熟悉Axios,但据我所知,在javascript和ajax中有一个选项

withCredentials: true

这将自动将cookie发送到客户端。例如,这个场景也是用passportjs生成的,它在服务器上设置了一个cookie

另一个解决方案是使用这个库:

https://github.com/3846masa/axios-cookiejar-support

它将“Tough Cookie”支持集成到Axios中。注意,这种方法仍然需要withCredentials标志。

在快速响应中设置必要的标头也很重要。以下是对我有用的方法:

app.use(function(req, res, next) {
res.header('Access-Control-Allow-Origin', yourExactHostname);
res.header('Access-Control-Allow-Credentials', true);
res.header('Access-Control-Allow-Headers', 'Origin, X-Requested-With, Content-Type, Accept');
next();
});

TL;博士:

{ withCredentials: true }axios.defaults.withCredentials = true


来自axios文档

withCredentials: false, // default

withCredentials表示是否应该使用凭据进行跨站点访问控制请求

如果你传递{ withCredentials: true }与你的请求,它应该工作。

更好的方法是将withCredentials设置为axios.defaults中的true

axios.defaults.withCredentials = true

如何让Axios在请求中自动发送cookie ?

设置axios.defaults.withCredentials = true;

或者对于某些特定的请求,你可以使用axios.get(url,{withCredentials:true})

这将给出CORS错误,如果你的'Access-Control-Allow-Origin'被设置为 通配符(*)。 因此,请确保指定请求的原始url

例如:如果您的前端使请求运行在localhost:3000上,则将响应头设置为

res.setHeader('Access-Control-Allow-Origin', 'http://localhost:3000');

res.setHeader('Access-Control-Allow-Credentials',true);

对于仍然不能解决的人来说,这个答案帮助了我。 Stackoverflow回答:34558264 < / p > < p > TLDR; 我们需要在两个axios的GET请求和POST请求(获取cookie)以及fetch中设置{withCredentials: true}

所以我也有同样的问题,我花了大约6个小时去寻找,我有

withCredentials: true

但是浏览器仍然没有保存cookie,直到出于某种奇怪的原因,我才想到重新调整配置设置:

Axios.post(GlobalVariables.API_URL + 'api/login', {
email,
password,
honeyPot
}, {
withCredentials: true,
headers: {'Access-Control-Allow-Origin': '*', 'Content-Type': 'application/json'
}});

似乎你应该总是先发送“withCredentials”密钥。

可以使用withCredentials属性在请求中传递cookie。

axios.get(`api_url`, { withCredentials: true })
通过设置{ withCredentials: true },你可能会遇到交叉起源问题。为了解决这个问题 你需要使用

expressApp.use(cors({ credentials: true, origin: "http://localhost:8080" }));

在这里你可以读到关于withCredentials

对我有用的是:

客户端:

import axios from 'axios';


const url = 'http://127.0.0.1:5000/api/v1';


export default {
login(credentials) {
return axios
.post(`${url}/users/login/`, credentials, {
withCredentials: true,
credentials: 'include',
})
.then((response) => response.data);
},
};

注意:凭证将是post请求的主体,在这种情况下,用户登录信息(通常从登录表单获得):

{
"email": "user@email.com",
"password": "userpassword"
}

服务器端:

const express = require('express');
const cors = require('cors');


const app = express();
const port = process.env.PORT || 5000;


app.use(
cors({
origin: [`http://localhost:${port}`, `https://localhost:${port}`],
credentials: 'true',
})
);

对于任何这些解决方案都不起作用的情况,请确保您的请求源等于您的请求目标,参见这个github问题

简而言之,如果您在127.0.0.1:8000访问您的网站,那么请确保您发送的请求是针对127.0.0.1:8001的服务器,而不是localhost:8001,尽管理论上可能是相同的目标。

这招对我很管用:

  • 首先,我必须使用自定义配置创建一个axios的新实例
  • 然后,我使用该axios实例发出post请求

参见下面的代码:

 const ax = axios.create({
baseURL: 'yourbaseUrl',
withCredentials: true,
});


const loginUser = () => { const body ={username:state.values.email, password:state.values.password};
ax.post('/login',body).then(function(response){
return response}).then().catch(error => console.log(error));}
< p >来源: https://www.npmjs.com/package/axios#creating-an-instance < / p >

法提赫的答案在2022年仍然有效。

同样axios.defaults.withCredentials = true也可以。

似乎不建议将{ withCredentials: true }传递给单独的axios调用。

这并不适用于每个人,但我使用了一个React前端与Vite,它正在服务localhost作为127.0.0.1:5173,这是我作为CORS允许域。只要我都localhost一切工作如预期!

//在创建axios实例时使用

const API = axios.create({
baseURL: "http://localhost:4000", // API URL
withCredentials: true,
});

//在后台的app.js中使用这个中间件 首先,安装cors npm i cors < / em >

var cors = require("cors"); // This should be at the end of all middlewares


const corsOptions = {
origin: "http://localhost:3000",
credentials: true, //access-control-allow-credentials:true
optionSuccessStatus: 200,
};


app.use(cors(corsOptions));

在尝试了2天之后,在尝试了这里的建议之后,这对我来说是有效的。

  1. < p >表达:

    • 歌珥:cors({ origin: "http:127.0.0.1:3000", credentials: true, })
    • Cookie:确保你的Cookie有 secure: true, sameSite: "None"
  2. < p >前端(反应)

    <李> axios.defaults.withCredentials = true; (withCredentials: true不为我工作)到您请求cookie的地方以及您发送cookie的地方(GET/POST)

希望这也能帮助到其他人。

就我而言,问题出在cookie上,而不是Axios;虽然我从/到相同的域/子域/主机接收和发送cookie,但我期望它在不同的路径上使用不同的资源-但我的cookie的行为就像我已经将它设置为单个Path,即使我省略了该属性。在cookie中显式地设置Path=/;解决了这个问题。