'CORS issue with one POST request but not another
I've looked at a few other questions, and they aren't having quite the same problem I'm having. I have a server running at localhost:5001 and a Vue website running at localhost:8080. When I do a /inventory/login post request, I'm not getting any CORS issues, but when I do a /inventory/computers request, I'm getting the following
Access to XMLHttpRequest at 'https://localhost:5001/inventory/computers' from origin 'http://localhost:8080' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.
What am I doing wrong? Here's the relevant code.
Startup.cs:
public void ConfigureServices(IServiceCollection services) {
var connection = Configuration.GetConnectionString("Inventory");
services.AddDbContextPool<InventoryContext>(options => options.UseSqlServer(connection));
services.AddControllers().AddNewtonsoftJson(options =>
options.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore);
services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme).AddJwtBearer(options => {
options.RequireHttpsMetadata = false;
options.SaveToken = true;
options.TokenValidationParameters = new TokenValidationParameters() {
ValidateIssuer = true,
ValidateAudience = true,
ValidAudience = Configuration["Jwt:Audience"],
ValidIssuer = Configuration["Jwt:Issuer"],
IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(Configuration["Jwt:Key"]))
};
});
services.AddCors(options => {
options.AddPolicy("AllowSpecificOrigin", builder => {
builder.WithOrigins("localhost")
.AllowAnyOrigin()
.AllowAnyHeader()
.AllowAnyMethod();
});
});
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env) {
if (env.IsDevelopment()) {
app.UseDeveloperExceptionPage();
}
app.UseHttpsRedirection();
app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();
app.UseCors();
app.UseEndpoints(endpoints => {
endpoints.MapControllers();
});
}
}
LoginController:
[Route("inventory/[controller]")]
[ApiController]
[EnableCors("AllowSpecificOrigin")]
public class LoginController : ControllerBase {
public IConfiguration _configuration;
private readonly InventoryContext _context;
public LoginController(IConfiguration config, InventoryContext context) {
_configuration = config;
_context = context;
}
[HttpPost]
public async Task<IActionResult> Post(LoginRequest req) {
if (req != null && req.Username != null && req.Password != null) {
User user = await _context.Users.FirstOrDefaultAsync(u => u.Username == req.Username);
if (user == null || !Crypto.VerifyHashedPassword(user.HashedPassword, req.Password)) {
return BadRequest("Invalid username or password.");
}
var claims = new[] {
new Claim(JwtRegisteredClaimNames.Sub, _configuration["Jwt:Subject"]),
new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString()),
new Claim(JwtRegisteredClaimNames.Iat, DateTime.UtcNow.ToString()),
new Claim("EmployeeID", user.EmployeeId.ToString()),
new Claim("Username", user.Username),
};
var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_configuration["Jwt:Key"]));
var signIn = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);
var token = new JwtSecurityToken(_configuration["Jwt:Issuer"], _configuration["Jwt:Audience"], claims, expires: DateTime.UtcNow.AddDays(1), signingCredentials: signIn);
return Ok(new JwtSecurityTokenHandler().WriteToken(token));
}
else {
return BadRequest();
}
}
ComputerController:
[Authorize]
[Route("inventory/[controller]")]
[ApiController]
[EnableCors("AllowSpecificOrigin")]
public class ComputersController : ControllerBase {
private readonly InventoryContext _context;
public ComputersController(InventoryContext context) {
_context = context;
}
// POST: api/Computers
// To protect from overposting attacks, enable the specific properties you want to bind to, for
// more details, see https://go.microsoft.com/fwlink/?linkid=2123754.
[EnableCors("AllowSpecificOrigin")]
[HttpPost]
public async Task<ActionResult<Computer>> PostComputer(ComputerPostRequest req) {
Item item = new Item("Computer");
_context.Items.Add(item);
await _context.SaveChangesAsync();
Computer computer = new Computer(item.ItemId, req.SelectBankcardSerialNumber, req.ManufacturerSerialNumber, req.Model, req.Name, req.Value, req.EmployeeID, req.DateObtained);
_context.Computers.Add(computer);
if (!String.IsNullOrEmpty(req.Notes)) {
Note note = new Note(computer.ComputerId, req.Notes, DateTime.Now);
_context.Notes.Add(note);
}
await _context.SaveChangesAsync();
return CreatedAtAction("GetComputer", new { id = computer.ComputerId }, computer);
}
And the Vue code:
Login.vue
async login() {
if (this.isEmpty(this.username) || this.isEmpty(this.password)) {
this.incorrect = true;
console.log("Something's wrong");
return false;
}
try {
let res = await axios.post('https://localhost:5001/inventory/login', {
username: this.username,
password: this.password
});
this.$root.$authToken = "Bearer " + res.data;
} catch (error) {
console.log(error);
}
}
Computers.vue:
async upload() {
if (this.isEmpty(this.sbSerialNum) || this.isEmpty(this.mSerialNum) || this.isEmpty(this.compModel) || this.isEmpty(this.compName) ||
this.value === 0.0 || this.empID === 0 || this.isEmpty(this.dateObtained) || this.isEmpty(this.notes)) {
this.incorrect = true;
console.log("Something's wrong");
return false;
}
try {
const options = {
headers: {'Authorization': this.$root.$authToken}
};
let res = await axios.post('https://localhost:5001/inventory/computers', {
SelectBankcardSerialNumber: this.sbSerialNum,
ManufacturerSerialNumber: this.mSerialNum,
Name: this.compName,
Model: this.compModel,
Value: this.value,
EmployeeID: this.empID,
DateObtained: this.dateObtained,
Notes: this.notes
}, options);
this.computerAdded = res.data;
} catch (error) {
console.log(error);
}
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|
