Cross-Origin Request Blocked
August 30, 2018 · 4 minute read · Tags: react
You’ve built a shiny new API using ASP.NET Core.
You can call it via a web browser (or one of my favourite tools, Insomnia) and everything works perfectly.
Then you try to call it from your front-end (React, Angular or whatever) and boom.
You get a cryptic error about a Cross-Origin Request being blocked, because the Same Origin Policy disallows reading the remote resource at somewhere or other…
So what is this?
Handy new tool alert: Check if you need CORs and generate the exact code to go in startup.cs
All modern browsers enforce something called a “Same origin policy”.
This is designed to prevent some random web site on the Internet from being able to make requests to your API.
Why does the Same Origin Policy exist?
Take this example.
I stand up an API at https://jonhilton.io/api and a front-end at the same domain (using something like React, Angular).
So far so good, I launch the site, everyone starts using https://jonhilton.io, which interacts with my API and everything is well in the world.
But then, disaster. One of my users is tricked into going to a spoof site, which looks like mine but is actually hosted over at https://dodgygeezer.com.
The page at https://dodgygeezer.com includes javascript to make calls to my api.
Without the same origin policy, there would be nothing to stop https://dodgygeezer.com from making these requests.
Same Origin Policy to the rescue
The same origin policy (implemented in the browser) does a number of things to try and protect your site from malicious use.
The main aspect we’re interested in when talking about AJAX requests is its ability to prevent code which is executed in the browser (e.g. your’s or someone else’s javascript) from making certain AJAX calls to a site at a different origin.
Origin refers to the domain of the page which serves the javascript.
For this example, the origin for legitimate requests from my site would be https://jonhilton.io
The origin for the dodgy imposter site would be https://dodgygeezer.com
The same origin policy attempts to limit what a client can do if it makes requests from an origin which the server does not trust.
By default, your ASP.NET Core Web API will allow any requests made from a site at the same origin. So any javascript served for https://jonhilton.io will be fine.
So why the problem when I’m calling my own API?
This is all well and good, but why are you seeing this error when your own front-end app tries to communicate with your api?
Well, if they’re both served from the same domain you’ll be fine.
Front-end: https://jonhilton.io
Back-end: https://jonhilton.io/api
Both are served from https://jonhilton.io and therefore have the same origin.
Front-end: https://jonhilton.io
Back-end: https://api.jonhilton.io
Now we have the problem. The sub-domain here means that these are considered to be different origins.
If you’re running your api and front-end site locally you’ll have the same problem due to different ports being used.
Front-end: https://localhost:3000
Back-end: https://localhost:5000
The different port here means these are considered different origins.
But how do I allow my own front-end to bypass this policy?
Let’s take this example.
Front-end: https://jonhilton.io
Back-end: https://api.jonhilton.io
If we want https://jonhilton.io to be able to make requests to https://api.jonhilton.io we need to configure our API to allow those requests by implementing a CORS policy for the API.
CORS = Cross Origin Resource Sharing
CORS lets you control which resources running in the browser (front-end applications) are expected to call your API.
In ASP.NET Core 2.x this is simply a matter of configuration.
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
// ...
app.UseCors(builder =>
builder.WithOrigins("https://jonhilton.io"));
app.UseHttpsRedirection();
app.UseMvc();
}
Make sure the app.UseCors
call is before app.UseMVC
otherwise it will have no effect on requests to your app which trigger the MVC pipeline (which is all MVC and API requests!).
And that’s it. If you examine any responses from your API now you’ll notice they include this response header.
This “Access-Control-Allow-Origin” header is the magic that ensures you won’t see the dreaded CORS error anymore.
Handy new tool alert: Check if you need CORs and generate the exact code to go in startup.cs
If you want more than one url to be permitted, you can simple add more to the list.
app.UseCors(builder =>
builder.WithOrigins(
"https://jonhilton.io",
"https://localhost:3000"));
GOTCHA: Omit the trailing slash!
Watch out for one thing. It’s very easy to accidentally include a trailing slash when adding an origin to the permitted origins list.
app.UseCors(builder =>
builder.WithOrigins(
"https://jonhilton.io/",
"https://localhost:3000/"));
But if you do, you’ll find you start seeing the “same origin policy” error again. This is one of those problems which can have you tearing your hair out because it “looks right” but the trailing slash will break your CORS!
photo credit: mikecogh Stained Board in Brick Frame via photopin (license)
All posts in the
Learning to use React with ASP.NET Core Web API series.
- Diary Of A Net Developer - Learning React
- Learning React - Building up the user interface using components and dummy data
- Learning React - How to connect React components to your ASP.NET Core Web API
- Learning React - Exercise control over your component state with Typescript
- Cross-Origin Request Blocked