[英]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 策略錯誤:
從源“ http://localhost:4200 ”訪問“ http://localhost:50501/CoordinatorHub/negotiate ”的 XMLHttpRequest 已被 CORS 策略阻止:對預檢請求的響應未通過訪問控制檢查:無“訪問” -Control-Allow-Origin' 標頭存在於請求的資源上。
但是我們 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'));
請注意,這可以應用於 .net core 3.1
正如它在 microsoft docs 上所說,它似乎不起作用docs
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
// Preceding code ommitted.
app.UseRouting();
app.UseCors();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
// Following code ommited.
}
警告
對於端點路由,必須將 CORS 中間件配置為在對 UseRouting 和 UseEndpoints 的調用之間執行。 不正確的配置將導致中間件停止正常運行。
但是,如果您首先移動 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.
}
接受的答案對我不起作用,所以我決定把對我有用的東西放在這里。 萬一有人偶然發現同樣的問題。
在 Angular 9 上使用 signalR 時,我在本地測試中遇到了同樣的問題。
我通過將我的 Asp NET Core (3.1) 應用 URL 從 https 切換到 http 來解決它。 如果您使用的是 Visual Studio,
也不要忘記在 angular App 中更改 URL 上的端口。 所以基本上角度應用程序中的 URL 將是這樣的
this.hubConnection = new signalR.HubConnectionBuilder()
.withUrl("http://localhost:50782/hub").build();
而配置方法中的相關代碼是這樣的
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();
希望這可以幫助 !
更新
如果你只是玩弄你的本地計算機上的樣品,你也可以嘗試運行安全模式鉻提到這里
在我的 Mac 上,我只是簡單地從終端運行命令
open -n -a /Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome --args --user-data-dir="/tmp/chrome_dev_test" --disable-web-security
有了這個,您應該能夠在沒有 CORS 打擾的情況下運行您的示例
我根據這個鏈接解決了我的問題
將此塊代碼添加到服務
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");
});
在你的啟動配置類中嘗試這樣的事情:
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);
});
我有一個類似的問題,我掙扎了 6 個小時。
原來我的起源結尾有一個斜線。
所以而不是:
.WithOrigins("https://aaa.azurewebsites.net/")
用:
.WithOrigins("https://aaa.azurewebsites.net")
為什么最后的斜線不只是被剝離超出了我的理解。
最近我在 .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();
}
在做了大量研究之后,我還想分享我所面臨的問題以及我是如何解決的。
我的情況是; 我在Azure App Services
上部署了我的.Net Core
應用以及Azure SignalR
配置。 當我在本地機器上運行前端和后端時,一切正常。 但是當我在 azure 服務上部署我的應用程序時,由於這個../Hub/negotiate
和 cors 問題,我無法連接。
我是如何修復的; 首先確保你已經在你的 api 中啟用了 cors 設置,正如這里的朋友指出的那樣。 我在此鏈接中從 Microsoft 文檔中獲取了我的示例 signalR 應用程序。 最后我意識到在項目示例中@aspnet/signalr@1.0.0
包已過時並移至@microsoft/signalr
。 在我的研究中,我在某些地方看到withCredentials
應該設置為 false,因為默認情況下該值為 true 並強制連接使用 SSL。 我的客戶端應用程序正在使用 http 本地運行並嘗試連接 https 連接。 有關更多信息,請參閱此鏈接。 在舊的 signalR npm 包中,這個值沒有設置,所以我一切換到新的, withCredentials
屬性被激活,我把它設置為 false。 一切都開始正常工作。
我最后的集線器建造者是這樣的;
var connection = new signalR.HubConnectionBuilder()
.withUrl('https://**chat.azurewebsites.net/chat', {
accessTokenFactory: () => 'InR5cCI6IkpXVCJ9.eyJpZCI6I',
withCredentials: false
}).build();
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.