2

Even though this question is asked several times at SO like:

fetch: Getting cookies from fetch response

or

Unable to set cookie in browser using request and express modules in NodeJS

None of this solutions could help me getting the cookie from a fetch() response

My setup looks like this:

Client

export async function registerNewUser(payload) { return fetch('https://localhost:8080/register', { method: 'POST', body: JSON.stringify(payload), credentials: 'same-origin', headers: { Accept: 'application/json', 'Content-Type': 'application/json' } }); } ... function handleSubmit(e) { e.preventDefault(); registerNewUser({...values, avatarColor: generateAvatarColor()}).then(response => { console.log(response.headers.get('Set-Cookie')); // null console.log(response.headers.get('cookie')); //null console.log(document.cookie); // empty string console.log(response.headers); // empty headers obj console.log(response); // response obj }).then(() => setValues(initialState)) } 

server

private setUpMiddleware() { this.app.use(cookieParser()); this.app.use(bodyParser.urlencoded({extended: true})); this.app.use(bodyParser.json()); this.app.use(cors({ credentials: true, origin: 'http://localhost:4200', optionsSuccessStatus: 200, // some legacy browsers (IE11, various SmartTVs) choke on 204 credentials: true })); this.app.use(express.static(joinDir('../web/build'))); } ... this.app.post('/register', (request, response) => { const { firstName, lastName, avatarColor, email, password }: User = request.body; this.mongoDBClient.addUser({ firstName, lastName, avatarColor, email, password } as User) .then(() => { const token = CredentialHelper.JWTSign({email}, `${email}-${new Date()}`); response.cookie('token', token, {httpOnly: true}).sendStatus(200); // tried also without httpOnly }) .catch(() => response.status(400).send("User already registered.")) }) 

enter image description here

7
  • httpOnly: true, prevents clientside access Commented Dec 1, 2019 at 15:04
  • Even though I removed this option value on the server side/directly set it to false. The client logs still the same values... Commented Dec 1, 2019 at 15:14
  • Have you confirmed you're indeed getting cookied from the backend? This is usually visible in your browser's devtools Commented Dec 1, 2019 at 15:18
  • updated my question accordingly.. Yes I checked that too. Commented Dec 1, 2019 at 15:20
  • That cookie appears to still be HTTPOnly. Commented Dec 1, 2019 at 15:21

2 Answers 2

2

I figured it out. The solution was to set credentials to 'include' like so:

export async function registerNewUser(payload) { return fetch('https://localhost:8080/register', { method: 'POST', body: JSON.stringify(payload), credentials: 'include', headers: { Accept: 'application/json', 'Content-Type': 'application/json' } }); } 

After that I needed to enabled credentials in my cors middleware:

 this.app.use(cors({ credentials: true, // important part here origin: 'http://localhost:4200', optionsSuccessStatus: 200 }) 

And then finally I needed to remove the option {httpOnly: true} in the express route response:

response.cookie('token', '12345ssdfsd').sendStatus(200); 

Keep in mind if you send the cookie like this, it is set directly to the clients cookies. You can now see that the cookie is set with: console.log(document.cookie).

But in a practical environment you don't want to send a cookie that is accessible by the client. You should usually use the {httpOnly: true} option.

Sign up to request clarification or add additional context in comments.

Comments

0

JavaScript fetch method won't send client side cookies and silently ignores the cookies sent from Server side Reference link in MDN, so you may use XMLHttpRequest method to send the request from your client side.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.