Skip to content

setting cookies via fetch and the proxy webpack dev server #2778

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
HUSSTECH opened this issue Jul 12, 2017 · 7 comments
Closed

setting cookies via fetch and the proxy webpack dev server #2778

HUSSTECH opened this issue Jul 12, 2017 · 7 comments

Comments

@HUSSTECH
Copy link

HUSSTECH commented Jul 12, 2017

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

@Timer
Copy link
Contributor

Timer commented Jul 13, 2017

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

@HUSSTECH
Copy link
Author

@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.

@HUSSTECH
Copy link
Author

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.

@PabloMessina
Copy link

@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

@HUSSTECH
Copy link
Author

HUSSTECH commented Sep 7, 2017

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

@PabloMessina
Copy link

PabloMessina commented Sep 7, 2017

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

@sripadkollur
Copy link

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('');
          }
        });
      },
    },
  },
}

@lock lock bot locked and limited conversation to collaborators Jan 19, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

4 participants