0

I am getting a CORS error and I don't know how to fix it. I have an Aurelia app, calling a .NET core 2.0 API using aurelia-fetch-client. I am getting the following error:

Failed to load http://localhost:58289/api/info: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:8080' is therefore not allowed access. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.

TypeError: Failed to fetch at applyInterceptors (webpack-internal:///./node_modules/aurelia-fetch-client/dist/native-modules/aurelia-fetch-client.js:428:14) at processResponse (webpack-internal:///./node_modules/aurelia-fetch-client/dist/native-modules/aurelia-fetch-client.js:411:10) at eval (webpack-internal:///./node_modules/aurelia-fetch-client/dist/native-modules/aurelia-fetch-client.js:299:14) From previous event: at HttpClient.eval (webpack-internal:///./node_modules/aurelia-fetch-client/dist/native-modules/aurelia-fetch-client.js:287:61) at HttpClient.fetch (webpack-internal:///./node_modules/aurelia-fetch-client/dist/native-modules/aurelia-fetch-client.js:273:21) at App.callApi (webpack-internal:///app:42:25) at CallScope.evaluate (webpack-internal:///./node_modules/aurelia-binding/dist/native-modules/aurelia-binding.js:1578:19) at Listener.callSource (webpack-internal:///./node_modules/aurelia-binding/dist/native-modules/aurelia-binding.js:5279:40) at Listener.handleEvent (webpack-internal:///./node_modules/aurelia-binding/dist/native-modules/aurelia-binding.js:5288:10) at HTMLDocument.handleDelegatedEvent (webpack-internal:///./node_modules/aurelia-binding/dist/native-modules/aurelia-binding.js:3363:20)

Please find my code below.

aurelia-fetch-client configuration:

const http = new HttpClient().configure(config => {
    config
        .withBaseUrl(environment.apiBaseUrl)
        .withDefaults({
          headers: {
              'Content-Type': 'application/json'
          }
        })
        .withInterceptor({
          request(request: Request) {
            var token = localStorage.getItem('access_token')
            request.headers.append('Authorization', 'Bearer ' + token)
            return request;
          },
          responseError(error){
            return error;
          }
      });
  });

  aurelia.container.registerInstance(HttpClient, http);

Call the API:

callApi(){
    this.httpClient.fetch("/info")
      .then(response => console.log(response));
  }

API startup configuration:

public void ConfigureServices(IServiceCollection services)
{
    string domain = $"https://{Configuration["Auth0:Domain"]}/";
    var allowedCors = Configuration["CorsSite"];

    services.AddAuthentication(options =>
    {
        options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
        options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;

    }).AddJwtBearer(options =>
    {
        options.Authority = domain;
        options.Audience = Configuration["Auth0:ApiIdentifier"];
    });
    services.AddCors(options => options.AddPolicy("AllowSpecificOrigin", `builder => {`
        builder.AllowAnyOrigin().AllowAnyMethod(); }));
    services.AddMvc();
}

// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
    app.UseCors("AllowSpecificOrigin");
    app.UseAuthentication();
    app.UseMvc();
}

Controller:

[Produces("application/json")]
[Route("api")]
public class InfoController : Controller
{
    // GET api/values
    [HttpGet]
    [Route("Info")]
    public IActionResult Get()
    {
        return Ok("Api V1.0");
    }

    [Route("authorizedInfo")]
    [Authorize]
    [HttpGet]
    public IActionResult GetAuthorized()
    {
        return Ok("Authorized Api V1.0");
    }
}

Please ignore the authorisation bit for now. I am only trying to hit the unauthorised API endpoint in localhost, but I am stuck. How can I fix my problem?

honk
  • 9,137
  • 11
  • 75
  • 83

2 Answers2

0

To do this start with registering CORS functionality in ConfigureServices() of Startup.cs:

public void ConfigureServices(IServiceCollection services)
{
    // Add service and create Policy with options
    services.AddCors(options =>
    {
        options.AddPolicy("CorsPolicy",
            builder => builder.AllowAnyOrigin()
            .AllowAnyMethod()
            .AllowAnyHeader()
            .AllowCredentials() );
    });


    services.AddMvc(); 
}

The AddCors() call above adds the CORS features to ASP.NET and creates a custom policy that can be reused in the application by name. There are other ways to do essentially the same thing by explicitly adding a policy builder in the configuration step but to me this seems cleanest - define one or more policies up front and then apply it.

Once the policy has been defined it can be applied.

You can apply the policy globally to every request in the application by call app.useCors() in the Configure() method of Startup:

public void Configure(IApplicationBuilder app)
{
    // ...

    // global policy - assign here or on each controller
    app.UseCors("CorsPolicy");

    // ...

    // IMPORTANT: Make sure UseCors() is called BEFORE this
    app.UseMvc(routes =>
    {
        routes.MapRoute(
            name: "default",
            template: "{controller=Home}/{action=Index}/{id?}");
    });
}

or you can apply the policy to individual controllers:

[EnableCors("CorsPolicy")]
[ApiExceptionFilter]
public class AlbumViewerApiController : Controller

Thank You

0

The answer in the following link fixed my issue.

Web API 2 CORS IIS Express Debug and No Access-Control-Allow-Origin header

It appears that if there is no origin header in the request the server will not respond with the corresponding Access-Control-Allow-Origin response. Also with aurelia-fetch-client defaults I would have expected to have the origin header added by default.