Start learning free

LESSON 96 OF 188 · BACKEND: USERS AND SECURITY

CORS

Practice

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 function that Flask calls after every route: decorate it with @app.after_request. It receives the answer and must return it. This one adds another header to every answer:

@app.after_request
def add_version(response):
    response.headers["X-Shop-Version"] = "2"
    return response

Before a request that sends a token or a JSON body, or uses PUT, the browser first asks with an OPTIONS request, a preflight. Flask answers OPTIONS by itself, and your function 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 an after_request function add_cors_headers that adds 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 add_cors_headers function.


Hint
Read the page's site with request.headers.get("Origin"), and set answer headers like dictionary keys: response.headers["..."] = .... Whatever happens, the function ends with return response.


STEP 1 OF 8
    Ctrl + Enter to check