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 added with app.Use that ASP.NET Core runs for every request, before its route. It can set headers on the answer, then calls next to pass the request on to its route. This one adds another header to every answer:
app.Use(async (HttpContext context, RequestDelegate next) => {
context.Response.Headers["X-Shop-Version"] = "2";
await next(context);
});
Before a request that sends a token or a JSON body, or uses PUT, the browser first asks with an OPTIONS request, a preflight. The shop's routes have no OPTIONS, so ASP.NET Core would answer 405. Your middleware answers it itself: after adding the headers, it returns without calling next, and the browser gets an empty 200. 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 add a middleware with app.Use that adds Access-Control-Allow-Origin, Access-Control-Allow-Headers and Access-Control-Allow-Methods only when the request's Origin is SHOP_SITE, ends OPTIONS requests with an empty 200, and passes every other request on to its route.
Assignment
Follow the Coding Tutorial to add the SHOP_SITE constant and the CORS middleware.
Hint
Read the page's site with context.Request.Headers["Origin"].ToString(), and set answer headers like dictionary keys: context.Response.Headers["..."] = .... Set them before await next(context): once the route starts writing its answer, the headers can't change.
Free plan: 30 tutor messages. PRO is unlimited.
