I've been battling this issue now for around 30 hours, and I just cannot seem to get by it. I'm having an issue with CORS in a .NET CORE 3.0.1 WebAPI project throwing the following error when called by my Angular project:
Access to XMLHttpRequest at 'http://localhost:4200/#/emailverified' (redirected from 'http://localhost:5000/api/auth/forgotpassword') from origin 'http://localhost:4200' has been blocked by CORS policy: Request header field content-type is not allowed by Access-Control-Allow-Headers in preflight response.
I have CORS setup in my startup.cs file as follows:
ConfigureServices method in Startup.cs:
services.AddCors(options => options.AddPolicy("CorsPolicy", p => p
.WithOrigins("http://localhost:4200")
.AllowAnyMethod()
.WithHeaders("content-type")
.AllowCredentials()
));
Configure method in Startup.cs:
app.UseCors("CorsPolicy");
The API Call that is being made from the Angular service
resetpassword(model: any) {
return this.http.post(this.baseUrl + 'forgotpassword', model);
}
The controller:
[AllowAnonymous]
[EnableCors("CorsPolicy")]
[HttpPost("forgotpassword")]
public async Task<IActionResult> ForgotPassword(SendPasswordResetDto sendPasswordReset)
{
if (sendPasswordReset.Email == null)
{
return NotFound("Please enter a valid email address");
}
var user = await _userManager.FindByEmailAsync(sendPasswordReset.Email);
// If the email does not exist, return null
if (user == null)
{
return Redirect($"{_configuration["ViewUrl"]}/#/emailverified");
}
// If the user email does exist, create a password reset token and encode it in a browser friendly way
var forgotPasswordToken = await _userManager.GeneratePasswordResetTokenAsync(user);
var encodedToken = Encoding.UTF8.GetBytes(forgotPasswordToken);
var validToken = WebEncoders.Base64UrlEncode(encodedToken);
// Send an email to the user with the reset email link
string url = $"{_configuration["ViewUrl"]}/#/changepassword?email={user.Email}&token={validToken}";
await _MailRepository.SendEmailAsync(user.Email, "Password Reset", $"<h1>You have requested to reset your password.</h1> <p>Please click <a herf='{url}'>this link</a> to reset your password. If it does not work, please copy and paste this link into your browser " + url + "</p>");
return Redirect($"{_configuration["ViewUrl"]}/#/emailverified");
}
And lastly these are the headers being sent with the request:
Request URL: http://localhost:4200/
Request Method: OPTIONS
Status Code: 200 OK
Remote Address: 127.0.0.1:4200
Referrer Policy: no-referrer-when-downgrade
Accept: */*
Accept-Encoding: gzip, deflate, br
Accept-Language: en-US,en;q=0.9
Access-Control-Request-Headers: content-type
Access-Control-Request-Method: POST
Cache-Control: no-cache
Connection: keep-alive
Host: localhost:5000
Origin: http://localhost:4200
Pragma: no-cache
Referer: http://localhost:4200/
Sec-Fetch-Dest: empty
Sec-Fetch-Mode: cors
Sec-Fetch-Site: same-site
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.61 Safari/537.36
I seriously cannot get past this and it is driving me absolutely nuts. Is there something I am missing here? I have added the "content-type" header to the CORS policy directly, but it just ignores it. I have searched high and low, and attempted about 2 dozen different ways of setting this up in my project. I've also tried clearing browser cache and using different browsers that have not been used on this project yet in case the cache was affecting it, and looking at the placement of app.UseCors("CorsPolicy") within the configure method, nothing seems to be getting this to work.
Is there something anyone can spot that I have missed?