moomou

(ノ≧∇≦)ノ ミ ┸┸

CORS with Cookie

Posted at — Aug 13, 2022

Introduction

CORS stands for Cross-Origin-Resource-Sharing and is the HTTP mechanism to allow servers to accept requests from other host locations other than its own.

Getting CORS up and running is not difficult. There are plenty of posts online that will recommend a starting configuration that looks something like this, in pseudo code

Header().Set("Access-Control-Allow-Origin", "*")
Header().Set("Access-Control-Allow-Methods", "POST, GET, OPTIONS, PUT, DELETE")
Header().Set("Access-Control-Allow-Headers", "Accept, Content-Type, Content-Length, Authorization")

This configuration works great and is the default I use; however, it does not work if you need to receive and set cookies in the browser. This short blog post documents what I learnt about working with cookies with CORS.

Setting Cookies

When I needed to set cookies in a server accessed behind CORS, I didn’t think anything special was needed as the CORS requests were completing without errors.

Cookies was not getting set however. It turned that browsers (tested on Chrome and Firefox) SILENTLY ignore cookie headers if CORS is not configured correctly.

Due to the lack of errors from browsers, it was not clear to me at first why cookie headers were not taking effect as I could see from curl that the backend was definitely replying with the correct cookie headers.

Stumped, I did what every good engineer do at this point, I Googled “set cookie header not setting cookie” and very quickly CORS came up as a possible culprit.

Turns out, in order for cookie headers to work across origin, the CORS header Access-Control-Allow-Origin must not specify * and instead needs to specify the requesting origin.

To put it concretely, for cookie header to be accepted by a browser, your server need to write, again in pseudo code

Header().Set("Access-Control-Allow-Origin", IncomingRequest.Host)

After this configuration change, setting cookie via CORS worked.

Receiving Cookies

Now that we can set cookies, receiving cookies on the server should just work automatically, right?

Almost. Fixing the CORS header Access-Control-Allow-Origin is a pre-requisite to setting and receiving cookies but turned out two more configuration updates are required.

First, from your web app, you need to make sure your AJAX request specifies withCredentials equal to true to make a request with cookies, which by default is not forwarded (presumably for security reasons).

Second, backend server needs to reply with Access-Control-Allow-Credentials: true or else the response will be dropped.

Summary

Interacting with cookie with CORS now works as expected, after many trials and errors, all of which could have been avoided had I read Mozill’s excellent MDN docs https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS first. Oh well