We need to configure CORS in .NET (or really in any other language) when an application’s front-end and back-end are being served from different domains, aka origins. And more than likely, during development, both the front-end and back-end will be running from different ports on localhost.
But what is CORS?
Cross-Origin Resource Sharing (CORS) is an HTTP-header based mechanism that allows a server to indicate any origins (domain, scheme, or port) other than its own from which a browser should permit loading resources.
From MDN
Basically, the server telling the browser “Hey, I only allow domains configured in my CORS policy, are you one of those?”
Enable CORS in .NET
CORS in .NET is enabled via middleware as follows
// Program.cs var builder = WebApplication.CreateBuilder(args); builder .services .AddCors(...); var app = builder.Build(); app.UseCors("PolicyName");
UseCors
must be placed after UseRouting
and before UseAuthorization
. This is to ensure that CORS headers are included in the response for both authorized and unauthorized calls. (From the official docs)
Configure CORS in .NET
It is important to have the front-end origin as a configuration in appsettings.json so that when deploying to upper environments and production, a configuration transformation can happen.
{ "CorsSettings": { "FrontendOrigin": "http://localhost:3050" } }
Rather than having the configuration in Program.cs
, I like to create a static class and a static method returning an Action
.
// Program.cs var builder = WebApplication.CreateBuilder(args); builder .services .AddCors(Cors.Configure(builder.Configuration)); // Static method that takes in IConfiguration var app = builder.Build(); app.UseCors(Cors.FrontEndPolicyName); // Policy name as a static prop in Cors class
In my static Cors
class, I read the front-end origin setting to use in the configuration.
// Cors.cs public static class Cors { public const string FrontEndPolicyName = "AllowFrontEnd"; public static Action<CorsOptions> Configure(IConfiguration configuration) { var frontendOrigin = configuration .GetSection(nameof(CorsSettings)) .Get<CorsSettings>()? .FrontendOrigin; // Only in .NET 8. In .NET 7 use .ThrowIfNullOrEmpty ArgumentException.ThrowIfNullOrWhiteSpace(frontendOrigin, nameof(frontendOrigin)); return options => { options .AddPolicy(name: FrontEndPolicyName, policy => { policy .WithOrigins(frontendOrigin) .AllowAnyHeader() .AllowCredentials(); policy.WithMethods("POST","GET"); } ); }; } }
WithOrigins
– Configure your front-end origin, or origins if more than oneAllowAnyHeader
– As the name implies, allow all headers from the browser. UseWithHeaders
if only allowing specific headersAllowCredentials
– This is required if you have a login page. The front-end will send credentials to the server and the server will respond withAccess-Control-Allow-Credentials: true
. The server will block the request otherwise.WithMethods
– Allow specific HTTP request methods. UseAllowAnyMethod
to allow all HTTP request methods.
BONUS! Configure Fetch API on the Front-End
fetch(`URL`, { method: 'POST', mode: 'cors', credentials: 'include', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify('{}'), });
Mode cors
must be included as an option in the request. credentials
must also be included.
If credentials
are not included, the request will not include the authentication cookie, and authenticated routes will not be reached.
If you liked this tutorial, share it on your social media and you can follow me on Twitter or LinkedIn.
Consider giving back by getting me a coffee (or a couple) by clicking the following button: