SignalR CORS问题与Angular和.net Core



我知道关于这个话题有很多问题和答案,但没有一个符合我的具体问题。

我正在使用以下版本

  • 角10.0.14
    • @aspnet/signalr 1.0.27
  • ASP。. NET Core 3.1

版本更新:

  • 我刚刚将@aspnet/signalr 1.0.27替换为@microsoft/signalr 5.0.11 ->同样的问题。

SignalR连接工作得很好,直到我在Angular前端添加了一个accessTokenFactory。

前端

this.hubConnection = new signalR.HubConnectionBuilder()
.withUrl(`${environment.bzApiBaseUrl}/hubs/heartbeat`, {
accessTokenFactory: () => token
})
.build();
this.hubConnection
.start()
.then(() => {
console.log('SignalR: Heartbeat - connection started');
this.hubConnection.on('beat', () => {
console.log('SignalR: Heartbeat - Heartbeat received');
});
})
.catch(err => console.log('SignalR: Heartbeat - error while starting connection: ' + err));
});

当我从HubConnectionBuilder中移除accessTokenFactory时,连接建立。

后端>
services.AddCors(options =>
{
options.AddPolicy(
name: MyAllowSpecificOrigins,
builder =>
{
builder
.WithOrigins(CorsSettings.TargetDomain)
.AllowAnyHeader()
.AllowAnyMethod()
.SetIsOriginAllowed((host) => true)
.AllowCredentials();
});
});

CorsSetting域的值为前端正在运行的http://localhost:4200

app.UseStaticFiles();
app.UseRouting();
app.UseCors(MyAllowSpecificOrigins);
app.UseAuthentication();
app.UseAuthorization();
app.UseEndpoints(e =>
{
e.MapControllers();
e.MapHub<HeartbeatHub>("/api/hubs/heartbeat");
});

添加accessTokenFactory后浏览器控制台出现以下错误:

WebSocketTransport.js:70 
WebSocket connection to 'ws://localhost:33258/api/hubs/heartbeat?id=BpBytwkEatklNR-XqGtabA&access_token=eyJ0eXAiOiJKV1QiLCJhbGci... failed:
Utils.js:190 
Error: Failed to start the transport 'WebSockets': undefined
dashboard:1 
Access to resource at 'http://localhost:33258/api/hubs/heartbeat?id=iWuMeeOKkWCUa8X9z7jXyA&access_token=eyJ0eXAiOiJKV1QiLCJhbGci...' from origin 'http://localhost:4200' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.

我不理解CORS问题,因为它似乎是通过使用accessTokenFactory向查询字符串添加令牌而引起的。

我试着:

  • 将后端URL添加到CORS源(根据文档不需要)
  • 应用程序。使用esignalr代替app.UseEndpoints
  • 禁用app.UseHttpsRedirection ()
  • 以不同方式更改注册中间件的顺序
  • .SetIsOriginAllowed((主机)=比;allowcredentials ()

更新

设置HttpTransportTypeLongPolling时连接建立。WebSocketsServerSentEvents不能使用

app.UseEndpoints(e =>
{
e.MapControllers();
e.MapHub<HeartbeatHub>("/api/hubs/heartbeat", options =>
{
options.Transports = HttpTransportType.LongPolling;
});
});

当使用长轮询时,令牌似乎作为HTTP头而不是查询字符串参数发送。令牌很长,所以我突破了最大值。使用WebSockets或ServerSentEvents时允许的URL长度。但是我仍然不知道为什么这会导致CORS异常。

浏览器不支持websockets的报头,因此必须将承载令牌添加为查询字符串参数。由于承载令牌的长度,我们达到了url的最大长度。我们可以缩短标记或使用引用标记,参见:https://github.com/aspnet/SignalR/issues/1266

希望这对其他人也有帮助。

最新更新