Create-react-app: setting cookies via fetch and the proxy webpack dev server

Created on 13 Jul 2017  路  7Comments  路  Source: facebook/create-react-app

Been at this problem for a while, appreciate any help. I'm using CRA with the proxy enabled in the webpack dev server to let me communicate to a Python API server running locally. I'm now trying to get cookie based authentication to work via the proxy by running an initial fetch (with credentials: 'include' set) that receives a cookie from the API server in the response.

So I'm getting the response from the server, and I see the Set-Cookie header present and with a cookie in the response, but the cookie is not making its way into other subsequent request. I know setting cookies are a browser's job, but I think here the browser is not setting it. Also I'm thinking could be something to do with the proxy set up? The proxy is somewhat of a cross-origin situation, so maybe the browser is choosing to silently not set the cookie. Including my request headers below for reference if it helps:

Request Headers seen in Browser dev tools

POST /login HTTP/1.1
Host: localhost:3000
Connection: keep-alive
Content-Length: 253
Origin: http://localhost:3000
User-Agent: Mozilla/5.0 etc...
content-type: multipart/form-data; boundary=----WebKitFormBoundaryKyB0fAkKFhnDbTx9
Accept: */*
Referer: http://localhost:3000/
Accept-Encoding: gzip, deflate, br
Accept-Language: en-GB,en-US;q=0.8,en;q=0.6

Request Headers as received by Python server (via proxy)

Referer: http://localhost:3000/
X-Forwarded-Host: localhost:3000
Origin: http://0.0.0.0:5000
Content-Length: 253
User-Agent: Mozilla/5.0 etc...
Connection: close
X-Forwarded-Proto: http
Host: 0.0.0.0:5000
Accept: */*
Accept-Language: en-GB,en-US;q=0.8,en;q=0.6
X-Forwarded-For: 127.0.0.1
X-Forwarded-Port: 3000
Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryeRTWYCMPpjO6jfD1
Accept-Encoding: gzip, deflate, br

Response Headers sent back as seen in Browser dev tools

HTTP/1.1 200 OK
X-Powered-By: Express
content-type: application/json
content-length: 42
set-cookie: session=<cookie-data>; HttpOnly; Path=/
server: Werkzeug/0.11.3 Python/2.7.12
date: Wed, 12 Jul 2017 21:39:58 GMT
connection: keep-alive
Vary: Accept-Encoding

Thanks

related issues I found here:

2159

828

question

Most helpful comment

Hi @PabloMessina, the credentials directive is not part of the headers object, it is its own option. So try something like this:

response = fetch(uri, {
    method: 'POST',
    body: body,
    headers: {stuff..},
    credentials: 'include'
})

All 7 comments

All subsequent uses of fetch must specify credentials: 'include'.

@Timer, I just double and triple checked to make sure I wasn't doing anything dumb. But all my fetch calls include credentials.

I also just built the bundle and served it from the same host as the API, and the cookies are still not being set. So mysterious! I can see the cookie being sent back to the browser, it's just not getting set.

Found and fixed!

Refactoring on this branch from the team and I meant I had a version with credentials included but an error on the form, and the others had a correct form but a credentials:include missing in a few places. Good thing this was a development branch.

Anyway, with this resolved it makes developing react with a different API so much easier. Thanks and closing.

@HUSSTECH
I'm having the same issue. The cookies are not being stored and I have tried with Chrome, Edge and Firefox to no avail. Would you mind sharing the exact code of your fetch requests?
In my case they look like this:

image
image

The network request looks like this (in Chrome):
image

However, the cookies store is empty:
image

Hi @PabloMessina, the credentials directive is not part of the headers object, it is its own option. So try something like this:

response = fetch(uri, {
    method: 'POST',
    body: body,
    headers: {stuff..},
    credentials: 'include'
})

Wow, that was it. Now it works like a charm, thanks @HUSSTECH!

The solution provided by HUSSTECH did not work for me. The browsers don't allow reading forbidden headers like 'set-cookie' from response and browser also does not allow setting 'Cookie' header. So I resolved this issue by reading cookie in onProxyRes and saving it in a variable and setting the saved cookie on following request in onProxyReq method.

let cookie;
devConfig.devServer = {  
  proxy: {
    '*': {
      target: https://target.com,
      secure: false, 
      changeOrigin: true, 
      onProxyReq: (proxyReq) => {
        proxyReq.setHeader('Cookie', cookie);
      },
      onProxyRes: (proxyRes) => {
        Object.keys(proxyRes.headers).forEach((key) => {
          if (key === 'set-cookie' && proxyRes.headers[key]) {
            const cookieTokens = split(proxyRes.headers[key], ',');
            cookie = cookieTokens.filter(element => element.includes('JSESSIONID')).join('');
          }
        });
      },
    },
  },
}
Was this page helpful?
0 / 5 - 0 ratings

Related issues

wereHamster picture wereHamster  路  3Comments

oltsa picture oltsa  路  3Comments

DaveLindberg picture DaveLindberg  路  3Comments

alleroux picture alleroux  路  3Comments

adrice727 picture adrice727  路  3Comments