I know this is a very common problem I faced myself in the past, but I was always able to deal with it enabling cors in DotNet Core Api startup.cs, but what's going on this time seems a little bit more weird.
My Angular 8 app does a post request first at login (this request inlcudes no httpHeader because no token is present yet) and it works (I have previously enabled cors for it to work).
After I get a token I store it in localstorage for later use, but to my big surprise when api controller has [Authorize] tag and the post includes header with token, then request fails with cors error and it doesn't even hit server method.
Error in vscode console:
Access to XMLHttpRequest at 'http://localhost:55909/api/manifest/add' from origin 'http://localhost:4200' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource. [http://localhost:4200/] Angular 8 post request that works (login) and I got return (token):
login(username: string, password: string) { return this.http.post<any>(`${environment.apiUrl}/api/login/authenticate`, { username, password }) .pipe(map(user => { let oUser = new User(); oUser.username = user['name']; oUser.token = user['token']; localStorage.setItem('currentUser', JSON.stringify(oUser)); let token = 'Bearer ' + JSON.parse(localStorage.getItem('currentUser')).token; this.currentUserSubject.next(user); return user; })); } Authenticate method in login controller that works:
[HttpPost] [Route("authenticate")] [EnableCors("Cors")] public ActionResult Authenticate(LoginRequest login) { if (!validCredentials(login)) return userUnauthorized(); TokenGenerator.settings = settings; var token = TokenGenerator.GenerateTokenJwt(login.Username); user.Token = token; return new JsonResult(new User { Name = user.Name, Token = user.Token }); } Angular 8 post request that fails:
this.headers = new HttpHeaders({ 'Authorization': 'Bearer ' + JSON.parse(localStorage.getItem('currentUser')).token, 'Content-Type': 'application/json' }); return this.http.post<any>(`${environment.apiUrl}/api/manifest/add`, { name, surname, seat, flight }, { headers: this.headers }) .pipe(map(result => { return result; })); Angular 8 post request that also fails:
this.headers = new HttpHeaders({ 'Authorization': 'Bearer ' + JSON.parse(localStorage.getItem('currentUser')).token, 'Content-Type': 'application/json', 'Access-Control-Allow-Origin': '*', 'Access-Control-Allow-Credentials': 'true', 'Access-Control-Allow-Headers': 'Content-Type, X-CSRF-Token, X-Requested-With, Accept, Accept-Version, Content-Length, Content-MD5, Date, X-Api-Version, X-File-Name', 'Access-Control-Allow-Methods': 'POST,GET,PUT,PATCH,DELETE,OPTIONS' }); return this.http.post<any>(`${environment.apiUrl}/api/manifest/add`, { name, surname, seat, flight }, { headers: this.headers }) .pipe(map(result => { return result; })); DotNet Core Api controller method that is not even get hit:
[Authorize] [HttpPost] [Route("add")] [EnableCors("Cors")] public ActionResult Add(Passenger passenger) { Response response = repository.addPassenger(passenger); return new JsonResult(response); } startup.cs "ConfigureServices" method where I enable cors:
public void ConfigureServices(IServiceCollection services) { services.AddHttpContextAccessor(); services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1); // Add functionality to inject IOptions<T> services.AddOptions(); // Add our Config object so it can be injected services.Configure<AppSettings>(Configuration.GetSection("AppSettings")); services.AddCors(o => o.AddPolicy("Cors", builder => { builder.AllowAnyOrigin() .AllowAnyMethod() .AllowCredentials() .AllowAnyHeader(); })); //Add repository to scope services.AddScoped<UserRepository>(); services.AddScoped<PassengerRepository>(); //sql connection and context (with crypted pass) var connection = getConnectionString(); services.AddDbContext<Context>(options => options.UseSqlServer(connection)); } The weird thing is if I remove [Authorize] directive from "Add" method then it works, but I obviously lose token validation.
Help, please :)