CORS (Part 1)
- Remove CORS headers from the API. Then try to run the app. Notice the CORS error in the browser.
- The problem is that JavaScript sent from website X (the React server) is trying to
connect to website Y (the ColorsAPI)
- Why is this a security issue? (Hint: Think about cookies.)
- Suppose you are logged into Facebook on Tab A. Then you visit
kittenpics.com
in
Tab B; but that site contains JavaScript code that makes a fetch
call to Facebook.
Your browser will send the session cookie and return the private data.
- Why is this a security risk? Your data is being sent to your machine?
- Because the “bad” JavaScript could take the data and send it somewhere else.
- Add the CORS header:
res.setHeader("Access-Control-Allow-Origin", "http://localhost:3000")
(Express)
response.headers["Access-Control-Allow-Origin"] = "http://localhost:3000"
(Rails)
- The protocol, hostname, and port must all match.
- Who is responsible for implementing this security feature? The browser or the server?
- The browser. The server returns the data, but the browser dumps it when it doesn’t find the correct CORS header.
- The security risk isn’t in sending the data (the credentials are, present after all).
- *!!! _The security risk is in what the browser does with it.
- You can configure some browsers to ignore CORS issues.
- You can write your own browsers to handle data however you want.
- Note: This is just one small part of CORS. It gets more complicated. Sorry.
ColorList React-side for new/update
- Look at
NewColorForm
- Notice that there is an ‘edit mode’ prop
- By default, this prop is
false
, which makes the form a “New color” form.
- Each color has an
Edit
button.
- Pressing an
edit
button calls a callback that takes the color as a parameter.
- This callback comes from the
App
level.
- Running this callback changes the
colorToEdit
and editMode
states, which are used by the form.
When they change, the form re-renders.
- Pressing the
cancel
button in the form re-sets these states.
- Notice how the state is stored at at level above the parts of the
tree
that affect it.
- Pressing
submit
sends a PUT
to the API.
CORS (Part 2)
- When submitting a
GET
, the browser refuses to deliver the data unless the API server “approves”
by means of an Access-Control-Allow-Origin
header.
- Why doesn’t this same approach work for a
POST
or PUT
?
- A
get
doesn’t modify the server and should (in theory) be harmless.
- A
POST
can modify the server. It needs to be approved before being issued.
- Solution: A “Preflight” request: An HTTP request with the
OPTIONS
verb that requests
CORS information.
- Browser then can use this information to decide whether it is safe to send the
POST
/PUT
/DELETE
request.
- CORS is complicated. Many options/configurations.
- In practice, we use libraries like
rack-cors
to get everything configured correctly.
- However, knowing why we have CORS, what types of settings need to be correct, and what the errors look like when they are wrong can be helpful in debugging issues.
- Remember: CORS is primarily implemented by the browser. It is the browser’s way of protecting you. Servers just do what they are told when given the proper credentials.
- Thus, be careful when using new/unfamiliar browsers, or using forks of browsers.
- Also don’t ever just get mad and tell your browser to turn off the protections!