If you are seeing this, you should at one point have been stuck in this issue or are stuck. We tend to solve the issue with different approaches without actually figuring out what the issue is. One of the major rescuers is adding a header of Access-Control-Allow-Origin in server’s response. Let’s dive into what is it and why did it arrise?
Well, One fact. Browsers work in a way which does not allow the server to distinguish how the call is made. When I log in to Instagram, they save my session in cookies. And whenever I make a request to Instagram from the browser (whichever tab), it checks first if there are any cookies for instagram. If there are, then it also sends these cookies along with the request. Now I am logged in to Instagram on one tab. And you are browsing a malicious website which tells you to click a button to get a lottery. 💰💰
Button onclick sends the request to instagram to like a post. Browsers adds the cookies to these requests. Instagram has no idea to know if the request came from malicious site or from instagram itself. Should it like that post?
Browser follows some rules. There is something called as Same Origin Policy. Origin is (scheme/host/port) triplet. That is if you are making a request to instagram.com from abhinavrai.com, or from localhost:3000 to localhost:4000, the browser will not allow it. CORS is actually the way to make this possible. So the above request will be blocked if you are using good browsers like chrome, firefox, opera, etc.
What happens when you make a cross origin request from a browser which has Same Origin Policy enabled?
There are 2 types of request which the browser can make — one is the normal request and other is preflight request. Normal requests are those which the browsers thinks are harmless to the server (GET request with only specific headers and content type values).
- So when you make a cross origin request and it’s a normal request, browser adds a header Origin (scheme/host/port) to the request.
- Server sees the request and returns the result with
Access-Control-Allow-Originas the origins which this server allow.
- The browser checks if the origin which sent this request is in this header. If not, then it shows the error.
The second type is the pre-flight request. As in the name, the one before the actual flight. The call which can be harmful to server — DELETE, POST with specific headers, Call with Authentication headers, etc.
- Pre-Flight requests is the OPTIONS call sent to the server to get all the allowed origin, methods and headers in the response headers.
- If the origin, method and headers for the call are there which the actual call supports, then we let the flight take off. Actual call is made. Else the browser shows the error.
Is CORS enabled for postman or curl?
CORS is something which is enforced by the browser. If we are making a curl call or by an API client like Postman, the server knows that you know what you are doing and sends the response.
What is CSRF?
CSRF stands for Cross Site Request Forgery. Remember the instagram example from above? That is the case of CSRF attack. One of the ways to stop it is by Same Origin Policy. CSRF is one of the major reasons the policy was made.
Another way is by CSRF token. For every session, there is a unique random token assigned to a user. So that whenever a POST request happens, the token is also sent along with data. The server first checks if the data has that token and the value is correct. If yes, then it allows. The malicious website (💰) does not have this token as that token is for the single session and one tab can’t read the data in another. Thus the server straight away rejects the call without the correct token.
How to solve CORS issue in Create-React-App?
My backend API server runs on “http://localhost:9000”. But my react app runs on “http://localhost:3000”. Origins are different (different port) hence welcome to the world of CORS errors. Development is really fast on React dev server. How React solves this issue?
You have to add “proxy” key in manifest.json with value as “http://localhost:9000”. So every request, say (‘/api/users/123’) would be sent to “http://localhost:9000/api/users/123”. How this works is — the webpack server makes a call to localhost:9000/api/users/123 and returns to result. There is proxy server implemented in it.
You may contact the author on firstname.lastname@example.org