配置AccessTokenProvider后SignalR客户端无法连接的问题
问题现象
- 未配置
AccessTokenProvider时,SignalR 连接可正常建立:
const connection = new signalR.HubConnectionBuilder() .withUrl('/ArgoRtc/Hub') .configureLogging(signalR.LogLevel.Information) .build();
- 添加
AccessTokenProvider配置后,连接失败,客户端报错:
SignalR connection failed: Unable to connect to the server with any of the available transports. WebSockets failed: Error: 'WebSockets' is disabled by the client. ServerSentEvents failed: Error: 'ServerSentEvents' is disabled by the client. LongPolling failed: Error: 'LongPolling' is disabled by the client.
根因分析
配置 AccessTokenProvider 后,SignalR 客户端会自动将返回的令牌以 Bearer {token} 格式注入 Authorization 请求头。若服务器未配置认证逻辑,可能对带该头的请求返回异常,导致客户端误判为传输方式被禁用;此外,纯字符串令牌(如直接返回 test)不符合 Bearer 规范,也可能引发协商流程异常。
解决方案
1. 遵循 Bearer 令牌规范修改返回值
若需保持使用 AccessTokenProvider,返回带 Bearer 前缀的令牌字符串:
const connection = new signalR.HubConnectionBuilder() .withUrl('/ArgoRtc/Hub', options => { options.AccessTokenProvider = () => { return 'Bearer test'; }; }) .configureLogging(signalR.LogLevel.Information) .build();
2. 手动设置请求头替代 AccessTokenProvider
若无需遵循 Bearer 规范,直接手动添加请求头,避免客户端自动处理逻辑:
const connection = new signalR.HubConnectionBuilder() .withUrl('/ArgoRtc/Hub', { headers: { "Authorization": "test" // 也可使用自定义头如 "X-Auth-Token": "test" } }) .configureLogging(signalR.LogLevel.Information) .build();
3. 确保服务器允许匿名访问 Hub
即使未配置认证,需明确允许 SignalR Hub 路径的匿名请求(以 ASP.NET Core 为例):
app.UseAuthorization(); app.MapHub<ArgoRtcHub>("/ArgoRtc/Hub") .AllowAnonymous();
服务器端令牌读取验证
通过以下代码读取请求头中的令牌:
var authToken = Context.GetHttpContext().Request.Headers["Authorization"].ToString();
若使用自定义头(如 X-Auth-Token),则调整为:
var authToken = Context.GetHttpContext().Request.Headers["X-Auth-Token"].ToString();
后续可通过 Hub 过滤器实现自定义认证逻辑,对读取到的令牌进行合法性校验。
内容的提问来源于stack exchange,提问作者Brobic Vripiat

