CORS demo
Table of Contents
1. Cross Origin Resourse Sharing
This button makes a request to Phil's echo-server running on the same machine:
Echo server response
req.open('POST', '/echo-server'); req.setRequestHeader("Content-type", "Application/json"); obj = {"hello": "world"} console.log("Sending object: ", obj) req.send(JSON.stringify(obj, null, 2));
On my home machine, I have nginx running with this configuration:
server { server_name philippe-carphin.ca; listen 443 ssl; # <other SSL stuff, certificates...> # Handle philippe-carphin.ca/~USERNAME location ~ ^/~(.+?)(/.*)?$ { disable_symlinks off; alias /Users/$1/public_html$2; # try_files $2 = 405; } # Proxy requests philippe-carphin.ca/echo-server to # localhost:5447 as unwrapped HTTP location /echo-server { proxy_pass http://localhost:5447; } }
CORS is explained at https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS#simple_requests
And an example is given in the section Simple Requests
where they show that the user visits https://website.com
and in the javascript of the web page makes a request
const fetchPromise = fetch("https://service.com"); fetchPromise .then((response) => response.json()) .then((data) => { console.log(data); });
This creates a request with headers that include
Origin: https://website.com
The server running at service.com inspects the headers of the request and if
it accepts to share with this origin, then it makes its response and includes
Access-Control-Allow-Origin: *
In my echo server, I check if the origin is one that I agree to share with:
if origin and args.allowed_origins and origin in args.allowed_origins: origin_allowed = True response_dict['info'].append(f"Origin {allowed_origin} is in allowed hosts") # else: # send_response(403) # return
and normally, if I don't agree to share with that origin, then I can send back a 403 and abort early rather than doing wasted work.
But if I do accept to share, then I do the work and tell the client inform the client by doing
self.send_response(200) self.send_header('Content-Type', 'application/json') self.send_header("Access-Control-Allow-Origin", origin) self.end_headers() self.wfile.write(bytes(json.dumps(response_dict, indent=' ') + '\n', 'utf-8'))
In this case, I am being more precise by sending back the exact value that I got
in the Origin header.
1.1. On Monday
- Copy
cors-demo.htmlandcors-demo.jsto the work computer in mypublic_html. - Change the Javascript request URL to
emmy.cmc.ec.gc.ca. - On Emmy, run my echo server with allowed origins
iweb.cmc.ec.gc.ca. Visit the page from
- https://emmy.cmc.ec.gc.ca/~carphinp/cors-demo.html
- https://iweb.cmc.ec.gc.ca/~carphinp/cors-demo.html
- https://ada.cmc.ec.gc.ca/~carphinp/cors-demo.html
and click the button to make a request to the echo-server running on Emmy.
Depending on the origin, we will get 3 behaviors
emmy: The echo server seesoriginthat is not part of the allowed origins. Since it doesn't abort the request, it just sends the normal response but withoutAccess-Control-Allow-Originin the headers.Since this is not a Cross Origin request, the client is OK with the fact that the response headers don't contain
Access-Control-Allow-Origin.iweb: The server seesiweb.cmc.ec.gc.caas the origin, it sends the response back withAccess-Control-Allow-Originwith a value equal to the origin it got in the request header.Since this request is a Cross Origin request, the client checks that the value of the response header
Access-Control-Allow-Originmatches is either*or matches the value of the request headerOrigin. In this case, it is a match, the client processes the response.ada: The request is a Cross Origin request. In this case my server accepts to process it for demonstration and does not set anAccess-Control-Allow-Originresponse header.The client made a cross origin request that came back with a response lacking the proper CORS header. It refuses to process the response.