CORS 政策不想与 SignalR 和 ASP.NET 核心一起工作
CORS policy don't want to work with SignalR and ASP.NET core
我的 ASP.NET 核心 API 和 Angular 客户端有问题。我想实现 SignalR 以在 API 和 Angular 之间建立连接。 cors 策略已经在我们的客户端和 API 上激活,因为我们已经可以与我们的客户端一起从 API 检索数据。但现在的问题是,当我尝试使用 SignalR 时,我收到了 CORS POLICY 错误:
Access to XMLHttpRequest at
'http://localhost:50501/CoordinatorHub/negotiate' from origin
'http://localhost:4200' 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.
但是我们 API 上的 Startup.cs 中已经有 cors 政策,就像这样:
在 ConfigureServices 方法中:
services.AddCors(options =>
{
options.AddPolicy("AllowSpecificOrigin",
builder =>
builder.WithOrigins("http://localhost:4200/")
.AllowCredentials()
//.AllowAnyOrigin()
.AllowAnyMethod()
.AllowAnyHeader()
.SetIsOriginAllowedToAllowWildcardSubdomains());
});
在 Configure 方法中:
app.UseCors("AllowSpecificOrigin");
在我们的客户端中,我们只想尝试在 API 和客户端之间建立连接,就像这样:
this.hubConnection.start({withCredentials: false}).then(() =>
this.hubConnection.invoke('send', 'Hello'));
在您的启动配置中尝试这样的事情 class:
app.Map("/CoordinatorHub/negotiate", map =>
{
map.UseCors(CorsOptions.AllowAll);
var hubConfiguration = new HubConfiguration
{
// You can enable JSONP by uncommenting line below.
// EnableDetailedErrors = true,
// EnableJSONP = true
};
map.RunSignalR(hubConfiguration);
});
注意这可以应用于.net core 3.1
正如微软文档中所述,它似乎不起作用
docs
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
// Preceding code ommitted.
app.UseRouting();
app.UseCors();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
// Following code ommited.
}
Warning
With endpoint routing, the CORS middleware must be configured to
execute between the calls to UseRouting and UseEndpoints. Incorrect
configuration will cause the middleware to stop functioning correctly.
但是,如果您首先移动 UseCors(),您的应用程序将按预期工作,因此工作代码将是
public void ConfigureServices(IServiceCollection services)
{
services.AddCors(options =>
options.AddDefaultPolicy(builder => builder.AllowAnyOrigin().AllowAnyHeader().AllowAnyMethod()));
}
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
//place your useCors here
app.UseCors();
app.UseRouting();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
// Following code ommited.
}
我按照这个解决了我的问题link
将此块代码添加到服务
services.AddCors(options => options.AddPolicy("CorsPolicy",
builder =>
{
builder.AllowAnyHeader()
.AllowAnyMethod()
.SetIsOriginAllowed((host) => true)
.AllowCredentials();
}));
并在配置应用程序中添加此块代码
app.UseCors("CorsPolicy");
app.UseSignalR(routes =>
{
routes.MapHub<General>("/hubs/general");
});
接受的答案对我不起作用,所以我决定在这里写下对我有用的答案。以防有人遇到同样的问题。
我在 Angular 9 上玩 signalR 时在本地测试中遇到了同样的问题。
我通过将我的 Asp NET Core (3.1) 应用 URL 从 https 切换到 http 解决了这个问题。如果您使用 Visual Studio,
- 只需右键单击项目属性 -> 调试。
- 取消选中启用 SSL
另外不要忘记在 angular 应用程序中更改 URL 上的端口。所以基本上 URL 在 angular 应用中会是这样的
this.hubConnection = new signalR.HubConnectionBuilder()
.withUrl("http://localhost:50782/hub").build();
而Configure方法中的相关代码是这样的
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseCors("_myAllowSpecificOrigins");
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapRazorPages();
endpoints.MapHub<ChatHub>("/hub");
});
并且在你的 configureServices 方法中我有以下内容
services.AddRazorPages();
services.AddCors(options =>
{
options.AddPolicy("_myAllowSpecificOrigins",
builder =>
{
builder.WithOrigins("https://localhost:4200")
.AllowAnyHeader()
.AllowAnyMethod()
.SetIsOriginAllowed((x) => true)
.AllowCredentials();
});
});
services.AddSignalR();
希望对您有所帮助!
更新
如果您只是在本地 machine 上玩弄示例,您也可以尝试 运行 chrome 在安全模式下 here[=16] =]
在我的 mac 上,我只是简单地从终端 运行 命令
open -n -a /Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome --args --user-data-dir="/tmp/chrome_dev_test" --disable-web-security
有了这个,您应该能够 运行 您的样本而不会受到 CORS 的影响
最近我在 .Net Core 3.1 上遇到了同样的问题,当我在 Azure App 服务中部署时问题开始,最后能够使用以下代码解决问题。
我在 Startup.cs 文件
的 ConfigureServices 函数中使用了以下代码
services.AddCors(options =>
{
var corsUrls = Configuration.GetSection("App:CorsOrigins").Value.ToString()
.Split(",", StringSplitOptions.RemoveEmptyEntries)
.Select(o => o.Trim('/'))
.ToArray();
options.AddPolicy("CorsPolicy",
builder =>
{
builder.WithOrigins(corsUrls)
.AllowAnyHeader()
.AllowAnyMethod()
.AllowCredentials();
});
});
然后在Configure函数中加入如下代码
app.UseCors("CorsPolicy");
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
endpoints.MapHub<WebhookHub>("/Webhook");
});
不要忘记在 appsetting.json 文件中添加以下部分
"App": {
"CorsOrigins": "https://myservice.com" }
在 .Net Core 3.1+ 和 Angular 8+ 版本和 android 19+ api 级别上测试了 signalR 并在 iOS 上工作设备太
.Net核心代码
public void ConfigureServices(IServiceCollection services)
{
services.AddCors(options =>
{
options.AddPolicy("CorsPolicy", builder => builder.WithOrigins("http://localhost:4200")
.AllowAnyMethod()
.AllowAnyHeader()
.AllowCredentials()
);
});
services.AddRazorPages();
services.AddAccessTokenService();
services.AddSignalR()
.AddHubOptions<ChatHub>(options => options.EnableDetailedErrors = true)
.AddJsonProtocol(options =>
{
options.PayloadSerializerOptions.PropertyNamingPolicy = null;
}); ;
services.AddSingleton<IUserIdProvider, NameUserIdProvider>();
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseCors("CorsPolicy");
app.UseAuthentication();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
endpoints.MapRazorPages();
endpoints.MapHub<ChatHub>("/chathub");
});
}
--Angular 代码将 url 和令牌(可选部分)替换为并且它正在工作--
public startConnection = () => {
this.hubConnection = new signalR.HubConnectionBuilder()
.withUrl(this.url,{ accessTokenFactory: () => this.token},)
.build();
this.hubConnection
.start()
.then(() => console.log('Connection started'))
.catch(err => console.log('Error while starting connection: ' + err))
}
ngOnInit(): void {
this.startConnection();
}
我有一个类似的问题,我为此苦苦挣扎了 6 个小时。
原来我的 Origins 结尾有个斜线。
所以代替:
.WithOrigins("https://aaa.azurewebsites.net/")
使用:
.WithOrigins("https://aaa.azurewebsites.net")
为什么最后的斜杠不只是被删除超出了我的理解。
经过大量研究后,我也想分享一下我遇到的问题以及我是如何解决的。
我的情景是;我在 Azure App Services
上部署了我的 .Net Core
应用程序以及 Azure SignalR
配置。当我 运行 在本地计算机上同时使用前端和后端时,一切都运行良好。但是当我在 azure 服务上部署我的应用程序时,由于这个 ../Hub/negotiate
和 cors 问题,我无法连接。
我是如何修复的;首先确保您已经在 api 中启用了 cors 设置,正如朋友们在此处指出的那样。我在此 link. Finally I realized that in project examples the @aspnet/signalr@1.0.0
package is outdated and moved to @microsoft/signalr
. And In my research I saw in some places that withCredentials
should be set to false because by default this value is true and forces the connection to use SSL. My client app is running on local with http and trying to connect https connection. For more of this, refer to this link 中从 Microsoft 文档中获取了我的示例 signalR 应用程序。在旧的 signalR npm 包中,这个值没有设置,所以我一切换到新的,withCredentials
属性就被激活,我把它设置为 false。一切开始正常工作。
我最后的hub builder是这样的;
var connection = new signalR.HubConnectionBuilder()
.withUrl('https://**chat.azurewebsites.net/chat', {
accessTokenFactory: () => 'InR5cCI6IkpXVCJ9.eyJpZCI6I',
withCredentials: false
}).build();
我的 ASP.NET 核心 API 和 Angular 客户端有问题。我想实现 SignalR 以在 API 和 Angular 之间建立连接。 cors 策略已经在我们的客户端和 API 上激活,因为我们已经可以与我们的客户端一起从 API 检索数据。但现在的问题是,当我尝试使用 SignalR 时,我收到了 CORS POLICY 错误:
Access to XMLHttpRequest at 'http://localhost:50501/CoordinatorHub/negotiate' from origin 'http://localhost:4200' 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.
但是我们 API 上的 Startup.cs 中已经有 cors 政策,就像这样:
在 ConfigureServices 方法中:
services.AddCors(options =>
{
options.AddPolicy("AllowSpecificOrigin",
builder =>
builder.WithOrigins("http://localhost:4200/")
.AllowCredentials()
//.AllowAnyOrigin()
.AllowAnyMethod()
.AllowAnyHeader()
.SetIsOriginAllowedToAllowWildcardSubdomains());
});
在 Configure 方法中:
app.UseCors("AllowSpecificOrigin");
在我们的客户端中,我们只想尝试在 API 和客户端之间建立连接,就像这样:
this.hubConnection.start({withCredentials: false}).then(() =>
this.hubConnection.invoke('send', 'Hello'));
在您的启动配置中尝试这样的事情 class:
app.Map("/CoordinatorHub/negotiate", map =>
{
map.UseCors(CorsOptions.AllowAll);
var hubConfiguration = new HubConfiguration
{
// You can enable JSONP by uncommenting line below.
// EnableDetailedErrors = true,
// EnableJSONP = true
};
map.RunSignalR(hubConfiguration);
});
注意这可以应用于.net core 3.1
正如微软文档中所述,它似乎不起作用 docs
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
// Preceding code ommitted.
app.UseRouting();
app.UseCors();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
// Following code ommited.
}
Warning
With endpoint routing, the CORS middleware must be configured to execute between the calls to UseRouting and UseEndpoints. Incorrect configuration will cause the middleware to stop functioning correctly.
但是,如果您首先移动 UseCors(),您的应用程序将按预期工作,因此工作代码将是
public void ConfigureServices(IServiceCollection services)
{
services.AddCors(options =>
options.AddDefaultPolicy(builder => builder.AllowAnyOrigin().AllowAnyHeader().AllowAnyMethod()));
}
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
//place your useCors here
app.UseCors();
app.UseRouting();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
// Following code ommited.
}
我按照这个解决了我的问题link
将此块代码添加到服务
services.AddCors(options => options.AddPolicy("CorsPolicy",
builder =>
{
builder.AllowAnyHeader()
.AllowAnyMethod()
.SetIsOriginAllowed((host) => true)
.AllowCredentials();
}));
并在配置应用程序中添加此块代码
app.UseCors("CorsPolicy");
app.UseSignalR(routes =>
{
routes.MapHub<General>("/hubs/general");
});
接受的答案对我不起作用,所以我决定在这里写下对我有用的答案。以防有人遇到同样的问题。
我在 Angular 9 上玩 signalR 时在本地测试中遇到了同样的问题。
我通过将我的 Asp NET Core (3.1) 应用 URL 从 https 切换到 http 解决了这个问题。如果您使用 Visual Studio,
- 只需右键单击项目属性 -> 调试。
- 取消选中启用 SSL
另外不要忘记在 angular 应用程序中更改 URL 上的端口。所以基本上 URL 在 angular 应用中会是这样的
this.hubConnection = new signalR.HubConnectionBuilder()
.withUrl("http://localhost:50782/hub").build();
而Configure方法中的相关代码是这样的
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseCors("_myAllowSpecificOrigins");
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapRazorPages();
endpoints.MapHub<ChatHub>("/hub");
});
并且在你的 configureServices 方法中我有以下内容
services.AddRazorPages();
services.AddCors(options =>
{
options.AddPolicy("_myAllowSpecificOrigins",
builder =>
{
builder.WithOrigins("https://localhost:4200")
.AllowAnyHeader()
.AllowAnyMethod()
.SetIsOriginAllowed((x) => true)
.AllowCredentials();
});
});
services.AddSignalR();
希望对您有所帮助!
更新
如果您只是在本地 machine 上玩弄示例,您也可以尝试 运行 chrome 在安全模式下 here[=16] =]
在我的 mac 上,我只是简单地从终端 运行 命令
open -n -a /Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome --args --user-data-dir="/tmp/chrome_dev_test" --disable-web-security
有了这个,您应该能够 运行 您的样本而不会受到 CORS 的影响
最近我在 .Net Core 3.1 上遇到了同样的问题,当我在 Azure App 服务中部署时问题开始,最后能够使用以下代码解决问题。
我在 Startup.cs 文件
的 ConfigureServices 函数中使用了以下代码services.AddCors(options =>
{
var corsUrls = Configuration.GetSection("App:CorsOrigins").Value.ToString()
.Split(",", StringSplitOptions.RemoveEmptyEntries)
.Select(o => o.Trim('/'))
.ToArray();
options.AddPolicy("CorsPolicy",
builder =>
{
builder.WithOrigins(corsUrls)
.AllowAnyHeader()
.AllowAnyMethod()
.AllowCredentials();
});
});
然后在Configure函数中加入如下代码
app.UseCors("CorsPolicy");
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
endpoints.MapHub<WebhookHub>("/Webhook");
});
不要忘记在 appsetting.json 文件中添加以下部分
"App": {
"CorsOrigins": "https://myservice.com" }
在 .Net Core 3.1+ 和 Angular 8+ 版本和 android 19+ api 级别上测试了 signalR 并在 iOS 上工作设备太
.Net核心代码
public void ConfigureServices(IServiceCollection services)
{
services.AddCors(options =>
{
options.AddPolicy("CorsPolicy", builder => builder.WithOrigins("http://localhost:4200")
.AllowAnyMethod()
.AllowAnyHeader()
.AllowCredentials()
);
});
services.AddRazorPages();
services.AddAccessTokenService();
services.AddSignalR()
.AddHubOptions<ChatHub>(options => options.EnableDetailedErrors = true)
.AddJsonProtocol(options =>
{
options.PayloadSerializerOptions.PropertyNamingPolicy = null;
}); ;
services.AddSingleton<IUserIdProvider, NameUserIdProvider>();
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseCors("CorsPolicy");
app.UseAuthentication();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
endpoints.MapRazorPages();
endpoints.MapHub<ChatHub>("/chathub");
});
}
--Angular 代码将 url 和令牌(可选部分)替换为并且它正在工作--
public startConnection = () => {
this.hubConnection = new signalR.HubConnectionBuilder()
.withUrl(this.url,{ accessTokenFactory: () => this.token},)
.build();
this.hubConnection
.start()
.then(() => console.log('Connection started'))
.catch(err => console.log('Error while starting connection: ' + err))
}
ngOnInit(): void {
this.startConnection();
}
我有一个类似的问题,我为此苦苦挣扎了 6 个小时。
原来我的 Origins 结尾有个斜线。
所以代替:
.WithOrigins("https://aaa.azurewebsites.net/")
使用:
.WithOrigins("https://aaa.azurewebsites.net")
为什么最后的斜杠不只是被删除超出了我的理解。
经过大量研究后,我也想分享一下我遇到的问题以及我是如何解决的。
我的情景是;我在 Azure App Services
上部署了我的 .Net Core
应用程序以及 Azure SignalR
配置。当我 运行 在本地计算机上同时使用前端和后端时,一切都运行良好。但是当我在 azure 服务上部署我的应用程序时,由于这个 ../Hub/negotiate
和 cors 问题,我无法连接。
我是如何修复的;首先确保您已经在 api 中启用了 cors 设置,正如朋友们在此处指出的那样。我在此 link. Finally I realized that in project examples the @aspnet/signalr@1.0.0
package is outdated and moved to @microsoft/signalr
. And In my research I saw in some places that withCredentials
should be set to false because by default this value is true and forces the connection to use SSL. My client app is running on local with http and trying to connect https connection. For more of this, refer to this link 中从 Microsoft 文档中获取了我的示例 signalR 应用程序。在旧的 signalR npm 包中,这个值没有设置,所以我一切换到新的,withCredentials
属性就被激活,我把它设置为 false。一切开始正常工作。
我最后的hub builder是这样的;
var connection = new signalR.HubConnectionBuilder()
.withUrl('https://**chat.azurewebsites.net/chat', {
accessTokenFactory: () => 'InR5cCI6IkpXVCJ9.eyJpZCI6I',
withCredentials: false
}).build();