I have defined an http interceptor. Inside the interceptor I have the following code:
let newReq = req.clone({
withCredentials: true,
responseType: 'json'
});
Now I need to modify all requests and add an extra header Demo
with the value of foo
I tried the following
let newReq = req.clone({
withCredentials: true,
responseType: 'json',
setHeaders: {'Demo' : 'foo'}
});
However I notice in the network tab that this removes almost all headers including Host
& Origin
from my request and it leads to CORS issues with the API that I am communicating with
Is there any way to fix this issue ? (I want to have all previous headers in my cloned request and just add a new one)
Your code seems to be working fine and and it does send the previous and new headers successfully. The culprit is the option withCredentials: true
which causes the following error:
Access to XMLHttpRequest at 'https://example.com' from origin 'http://localhost:4200' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: The value of the 'Access-Control-Allow-Origin' header in the response must not be the wildcard '*' when the request's credentials mode is 'include'. The credentials mode of requests initiated by the XMLHttpRequest is controlled by the withCredentials attribute.
As the error suggests, the server is probably sending header Access-Control-Allow-Origin: *
in pre-flight check (response of OPTIONS request). Your request will only work if server sends the header Access-Control-Allow-Origin: http://localhost:4200 (or whatever your origin is)
.
The reason why you cannot Access-Control-Allow-Origin: *
in combination with withCredentials: true
is explained here: CORS: Cannot use wildcard in Access-Control-Allow-Origin when credentials flag is true
I created a backend to reproduce this issue. Doing following steps will solve your problem:
http://localhost:4200
(or your origin) to the allow CORS origin list (you cannot set it as *
).access-control-allow-headers
to *
.allow_credentials
in your CORS settings to true
.If you are using Python (Fast API), you can do above settings like this (tested and works):
app = FastAPI()
origins = [
"http://localhost:4200"
]
app.add_middleware(
CORSMiddleware,
allow_origins=origins,
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
)
If you are using .NET Core, you can do above settings like this (not tested):
var MyAllowSpecificOrigins = "_myAllowSpecificOrigins";
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddCors(options =>
{
options.AddPolicy(MyAllowSpecificOrigins,
policy =>
{
policy.WithOrigins("http://localhost:4200")
.AllowAnyHeader()
.AllowAnyMethod()
.AllowCredentials();
});
});
builder.Services.AddControllers();
var app = builder.Build();
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseCors(MyAllowSpecificOrigins);
app.UseAuthorization();
app.MapControllers();
app.Run();
Also do similar settings on IIS (if you are using IIS).
allowCredentials="true"
allowAllRequestedHeaders="true"
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<system.webServer>
<cors enabled="true" failUnlistedOrigins="true">
<add origin="http://localhost:4200"
allowCredentials="true"
maxAge="120">
<allowHeaders allowAllRequestedHeaders="true">
<add header="Demo" />
</allowHeaders>
<allowMethods>
<add method="DELETE" />
<add method="GET" />
<add method="POST" />
<add method="PUT" />
<add method="OPTIONS" />
</allowMethods>
</add>
</cors>
</system.webServer>
</configuration>