77

I'm trying to authenticate express API back-end using Axios HTTP request call. I was able to see 'Set-Cookie' in the response header, but cookie was not set. Is it possible to set cookies through Axios HTTP calls?

Access-Control-Allow-Origin: *
Connection: keep-alive
Content-Length: 355
Content-Type: application/json; charset=utf-8
Date: Fri, 28 Sep 2018 05:59:01 GMT
ETag: W/"163-PAMc87SVHWkdimTJca7oRw"
Set-Cookie: token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...; Max-Age=3.6; Path=/; Expires=Fri, 28 Sep 2018 05:59:04 GMT; HttpOnly
X-Powered-By: Express
Mandakh
  • 1,073
  • 1
  • 9
  • 10

5 Answers5

81

Try this out!

axios.get('your_url', {withCredentials: true}); //for GET
axios.post('your_url', data, {withCredentials: true}); //for POST
axios.put('your_url', data, {withCredentials: true}); //for PUT
axios.delete('your_url', data, {withCredentials: true}); //for DELETE

For more information on this from the axios docs:

"withCredentials indicates whether or not cross-site Access-Control requests should be made using credentials" - https://github.com/axios/axios

More detail on withCredentials:

https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/withCredentials

shaithana
  • 2,470
  • 1
  • 24
  • 37
Aaron
  • 1,226
  • 9
  • 10
  • 10
    It works! Also I needed to add app.use(cors({ credentials: true })); on express API. I found out that Ajax requests ignore Cookies in CORS calls without credentials. Thanks @Aaron – Mandakh Sep 28 '18 at 07:46
  • Happy I could help! – Aaron Sep 28 '18 at 07:47
  • `withCredentials` is useful only for HTTP Basic Authentication – Billal Begueradj Nov 25 '19 at 12:53
  • 1
    @Begueradj `withCredentials` is also useful for sending and setting cookies. – Aposhian Apr 30 '20 at 15:57
  • @Aaron With this solution, I succeeded to pass request param body with form data. But when I changed to json, it responds error showing that I was blocked by CORS policy. This is what I tried axios.post('URL', data, { withCredentials: true }); – Lee Dat May 10 '20 at 03:14
  • 1
    @LeeDat This might fix your problem but I’m not 100% certain. I’m thinking you’ll need to set the ‘Content-Type’ header to something CORS compliant. Check out this thread https://stackoverflow.com/a/39012388 – Aaron May 10 '20 at 03:48
  • It works! However, one more issue I'm facing is that the cookie doesn't submit by default to my backend. I've already followed add withCredentials to attach cookie to the request. – Lee Dat May 10 '20 at 04:20
32

Yes you can set cookies by Axios. The cookies need to be passed into the headers object. You can send cookies in a get/post/put/delete/etc. request: As suggested by Aaron:

axios.get('URL', {
  withCredentials: true
}); 
axios.post('URL', data, {
withCredentials: true
}); 
axios.put('URL', data, {
withCredentials: true
});
axios.delete('URL', data, {
withCredentials: true
});

Or you may also try this:

axios.get(url, {
            headers: {
                Cookie: "cookie1=value; cookie2=value; cookie3=value;"
            }
        }).then(response => {
              console.log(response);
});
Amuk Saxena
  • 1,521
  • 4
  • 18
  • 44
  • 6
    I tried this way, but the browser keep telling me `Refused to set unsafe header "Cookie"` – kenshinji Feb 21 '19 at 03:34
  • @kenshinji You get that error from browser because, per the XHR specification, the setRequestHeader method should not set headers with a forbidden header name. – Amuk Saxena Apr 27 '19 at 15:52
14

In case anyone else faces the problem I've had,

Here's a repost of my answer on a similar question https://stackoverflow.com/a/62821342/8479303


In my case, the network panel showed that the response had the 'Set-Cookie' header, but in axios the header wouldn't show up, and the cookie was being set.

For me, the resolution was setting the Access-Control-Expose-Headers header.

For explanation, from this comment on an issue in the axios repository I was directed to this person's notes which led me to set the Access-Control-Expose-Headers header -- and now the cookie is properly setting in the client.

So, in Express.js, I had to add the exposedHeaders option to my cors middleware:

const corsOptions = {
  //To allow requests from client
  origin: [
    "http://localhost:3001",
    "http://127.0.0.1",
    "http://104.142.122.231",
  ],
  credentials: true,
  exposedHeaders: ["set-cookie"],
};

...

app.use("/", cors(corsOptions), router);

It was also important that on the axios side I use the withCredentials config in following axios requests that I wanted to include the cookies.

ex/

const { data } = await api.get("/workouts", { withCredentials: true });
jnotelddim
  • 1,806
  • 17
  • 32
6

I tried setting withCredentials: true but was still getting this error:

Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at http://localhost:4000/users/register. (Reason: CORS request did not succeed).

CORS was configured to allow requests from the frontend port.

I had to change the default options for axios like so:

axios.defaults.withCredentials = true

And the issue was solved. No error and Set-Cookie working as expected.

Nicolas Hevia
  • 15,143
  • 4
  • 22
  • 31
0

cookie can't be touched, the thing is it gets bundled to request object after appended to the response object.

function sign(req,res){
  res.cookie("x-token", signed, { maxAge: (new JWTService().jwtExpirySeconds * 
   1000) });
}

client after receiving this response just have to continue with requests, set-cookie in the name of "Cookie " will be bundled to those request, like this Response header from backend

Subsequent request headers will have Cookie

caveat: when http cookie expires its is automatically removed and not bundled to request there after.

Proau
  • 53
  • 3