Your browser runs the JavaScript of every page you open. So browsers follow a rule: a page may read answers only from its own site, unless the other site allows it. Without that rule, a page on evil.example.com could call the shop's API from your browser and read your data. The way a site says which other sites may read its answers is CORS (Cross-Origin Resource Sharing).
The browser names the page's site in the request header Origin. When that site is allowed, the API answers with the header Access-Control-Allow-Origin, and the browser lets the page read the answer. Every answer needs the rule, errors too, so it goes in a middleware: a function that Express runs before every route, once you pass it to app.use above the routes. It receives req: Request, res: Response and next: NextFunction, can already put headers on the answer, and must call next() to let the request go on. This one adds another header to every answer:
function addVersion(req: Request, res: Response, next: NextFunction) {
res.set("X-Shop-Version", "2");
next();
}
app.use(addVersion);
Before a request that sends a token or a JSON body, or uses PUT, the browser first asks with an OPTIONS request, a preflight. Express answers OPTIONS by itself, with the list of the methods that path has, and your middleware adds headers to that answer too: which headers and methods the shop's site may send. CORS is a rule the browser follows, not a lock: the shop still answers other sites, only without permission.
GET /products/1 Origin: https://shop.example.com → 200, Access-Control-Allow-Origin: https://shop.example.com GET /products/1 Origin: https://evil.example.com → 200, no Access-Control-Allow-Origin GET /products/99 Origin: https://shop.example.com → 404, Access-Control-Allow-Origin: https://shop.example.com OPTIONS /me Origin: https://shop.example.com → 200, Access-Control-Allow-Headers: Authorization, Content-Type OPTIONS /me/password Origin: https://shop.example.com → 200, Access-Control-Allow-Methods: GET, POST, PUT OPTIONS /me Origin: https://evil.example.com → 200, no CORS headers
Your task: keep the shop's website in a constant SHOP_SITE, and write a middleware addCorsHeaders, passed to app.use above the routes, that sets Access-Control-Allow-Origin, Access-Control-Allow-Headers and Access-Control-Allow-Methods only when the request's Origin is SHOP_SITE.
Assignment
Follow the Coding Tutorial to add the SHOP_SITE constant and the addCorsHeaders middleware.
Hint
Read the page's site with req.get("Origin"), and set answer headers with res.set(name, value). Give the parameters the same types as in loginRequired. Whatever happens, the function ends with next();.
Free plan: 30 tutor messages. PRO is unlimited.
