Robert
Robert

Reputation: 393

Angular 9 and .NET Core - access from origin localhost:4200 has been blocked by CORS policy

I have application in Angular 9 and backend in .NET Core 3.1 When I want to make request from angular client:

private httpHeaders: HttpHeaders;

  constructor(private httpClient: HttpClient, @Inject('BASE_URL') private baseUrl: string) {
    this.httpHeaders = new HttpHeaders({
      'Access-Control-Allow-Origin': '*' 
  });
  }

 return this.httpClient.get<any>(`${environment.apiUrl}/findUser/GetUsers?name=${name}&lastname=${lastname}`, {
        headers: this.httpHeaders,
      reportProgress: true,
      observe: 'events'
    });

In Startup.cs my settings looks like that:

services.AddCors();
 services.AddControllers();

app.UseCors(x => x
                .AllowAnyOrigin()
                .AllowAnyMethod()
                .AllowAnyHeader());

In controller:

[HttpGet]
[Route("getUsers")]
public IEnumerable<UserAccountDTO> GetUsers(string name, string lastname)
{}

But it doesn't work:

  Access to XMLHttpRequest at 'http://localhost:20677/findUser/GetUsers?
name=&lastname=John' from origin 'http://localhost:4200' has been blocked by CORS
 policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.

This is request:

GET /findUser/GetUsers?name=&lastname= HTTP/1.1
Host: localhost:20677
Connection: keep-alive
Access-Control-Allow-Origin: *
Accept: application/json
Authorization: Bearer xxxxxxxxxxxxxxx
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.89 Safari/537.36
Content-Type: application/json
Origin: http://localhost:4200
Sec-Fetch-Site: same-site
Sec-Fetch-Mode: cors
Sec-Fetch-Dest: empty
Referer: http://localhost:4200/find-user
Accept-Encoding: gzip, deflate, br
Accept-Language: en-US,en;q=0.9

Upvotes: 9

Views: 16997

Answers (6)

B.Nishan
B.Nishan

Reputation: 686

Steps:

  1. Install nugut package
    Microsoft.AspNetCore.Cors

  2. Add this in Startup.cs under ConfigureServices

    services.AddCors();
    
  3. Add this in Startup.cs under Configure

    app.UseCors(x => x.AllowAnyMethod()
                      .AllowAnyHeader()
                      .SetIsOriginAllowed(origin => true) // allow any origin
                      .AllowCredentials());
    

Upvotes: 1

Eliseo
Eliseo

Reputation: 57909

I think that is, see the docs

// in ConfigureServices
public void ConfigureServices(IServiceCollection services)
{
    services.AddCors(options =>
    {
        options.AddPolicy(
            name: "AllowOrigin",
            builder =>{
                builder.AllowAnyOrigin()
                        .AllowAnyMethod()
                        .AllowAnyHeader();
            });
    });
}

// in Configure
public void Configure(IApplicationBuilder app)
{
    app.UseCors("AllowOrigin");
}

NOTE: I updated the answer after received an ok; I missed a double quote in UseCors.


UPDATED 17.04.2021

app.UseCors("AllowOrigin"); must be located top of the others middlewares.

Upvotes: 20

Robert
Robert

Reputation: 393

In Startup.cs I added:

services.AddCors();

and

    app.UseRouting();

    app.UseCors(x => x
        .AllowAnyOrigin()
        .AllowAnyMethod()
        .AllowAnyHeader());
    // app.UseCors("AllowOrigin");



    // custom jwt auth middleware
    app.UseMiddleware<JwtMiddleware>();

And I have two controllers:

WheaterController generated by Visual Studio:
[EnableCors()]
    [ApiController]
    [Route("[controller]")]
    public class WeatherForecastController : ControllerBase
    {
       [HttpGet]
       [Route("getwheater")]
       public IEnumerable<WeatherForecast> Get()
       {
       }
}

And controller created by my:

[EnableCors()]
    [ApiController]
    [Route("[controller]")]
    public class FindUserController : ControllerBase
    {
       [HttpGet]
       [Route("getusers2")]
       public IEnumerable<UserAccountDTO> GetUsers2()
       {
           return new List<UserAccountDTO>();
       }
    }

When I call request from Angular to WheaterController it works, but when I call to FindUserController I have error as above: cors etc. What is the deference between two controllers?


Now I know where is the problem. In the constructor I had interface that wasn't added in Startup.cs in dependency injection and Visual shows me that error like CORS Thanks for help.

Upvotes: 0

Hansaka Sandaruwan
Hansaka Sandaruwan

Reputation: 521

I used this in several projects and it works perfectly for me.

services.AddCors(o => o.AddPolicy("CorsPolicy", builder =>{
                builder
                .AllowAnyMethod()
                .AllowAnyHeader()
                .WithOrigins("http://localhost:4200","other domains");
                
            }));

Note: this code goes in statUp.cs

Upvotes: 1

Caius Jard
Caius Jard

Reputation: 74595

You seem to have your understanding of CORS the wrong way round; I see your client side code adds a CORS header in its request, but that it's the way round it works.

  • The browser knows where the app was downloaded from (http://localhost:4200)
  • The browser knows where the app is requesting data from (http://localhost:20677/findUser/GetUsers? name=&lastname=John)
  • The browser sees that these are different
  • Before the browser acts on your code's request to get/post/whatever to http://localhost:20677/findUser/GetUsers? name=&lastname=John it first issues a separate request OPTIONS http://localhost:20677/findUser/GetUsers? name=&lastname=John to the server at :4200
  • This is like saying "hey 20677, this app some other website served me is trying to get data from you. What sites in the world do you allow this for?"
  • If the site at 20677 says "we allow 4200" or "we allow any" then the request will succeed. If the site says something else, or nothing (no Access-Control-Allow-Origin header is present on the response to the OPTIONS) then the browser flat refuses to do the GET/POST/ETC your code wants to do

If you're seeing this message in the console it means that the server at 20677 did NOT add the CORS headers in response to the OPTIONS request. Check the configuration of the 20677 server and use the dev console to look at what headers it sends

Upvotes: -2

Adrian Brand
Adrian Brand

Reputation: 21628

You use a proxy file, create proxy.config.json

{
  "/api/*": {
    "target": "http://localhost:20677/api",
    "pathRewrite": {
      "^/api": ""
    },
    "changeOrigin": true,
    "secure": false,
    "logLevel": "debug"
  }
}

and serve with

ng serve --proxy-config proxy.config.json

Upvotes: 0

Related Questions