简体   繁体   中英

Problems with SignalR WebSockets in JavaScript using accessTokenFactory

When connecting my js client to a SignalR hub in a net 5 service everything works fine as long as there is no token in game. I get a WebSockets connection without any problems.

As soon as there is a token for authorization i just get long polling. I tried with Firefox, Edge and Chrome.

My client code:

 <script> var token = document.getElementById("SignalRToken").value; var server = document.getElementById("CloudServer").value; const connection = new signalR.HubConnectionBuilder().withUrl(server, { accessTokenFactory: () => token }).configureLogging(signalR.LogLevel.Trace).withAutomaticReconnect().build(); connection.on("DevicePowerChanged", function (deviceId, power) { console.log("got power: " + power + " for " + deviceId); if (power) { document.getElementById("power").src = "/Images/power-on.png"; } else { document.getElementById("power").src = "/Images/power-off.png"; } }); connection.start().then(_=> console.log("signal-r connection established successfully.")).catch(err => console.error(err.toString())); </script>

the console log of my browser tells me, that the only possible transport layer is long polling.

What do I do wrong? What did I forget?
Why are there no valid credentials in WebSockets?
Why returns the connection request with SSE unauthorized?
Why is everything fine with Long Polling?

the console output of edge

signalr.js:2160 [2021-06-16T08:08:21.267Z] Debug: Starting HubConnection.
signalr.js:2160 [2021-06-16T08:08:21.267Z] Debug: Starting connection with transfer format 'Text'.
signalr.js:2160 [2021-06-16T08:08:21.268Z] Debug: Sending negotiation request: http://192.168.0.148:5001/signal-r/devices/negotiate?negotiateVersion=1.
signalr.js:2160 [2021-06-16T08:08:21.423Z] Debug: Selecting transport 'WebSockets'.
signalr.js:2160 [2021-06-16T08:08:21.424Z] Trace: (WebSockets transport) Connecting.
signalr.js:5071 WebSocket connection to 'ws://192.168.0.148:5001/signal-r/devices?id=ldKsTwHBD2T4TvZHT6Ii3w&access_token=eyJhbGciOiJSUzI1NiIsImtpZCI6IjcwRDkzRDY4M0MzRDZFMEI5ODk3NkZBQTlFNDQyM0REIiwidHlwIjoiYXQrand0In0.eyJuYmYiOjE2MjM4MzA4ODYsImV4cCI6MTYyMzgzNDQ4NiwiaXNzIjoiaHR0cHM6Ly9wYXRhdWdlb2lyZS1hdXRoZW50aWNhdGlvbi5henVyZXdlYnNpdGVzLm5ldCIsImNsaWVudF9pZCI6InJhc3BlcnJ5UGllIiwianRpIjoiM0ZFQzU4RDI4QTI3MDQxQ0Q2QTIzNTE2OUMwMDVBOUMiLCJpYXQiOjE2MjM4MzA4ODYsInNjb3BlIjpbIlNpZ25hbFJqcyJdfQ.XkQMI9CWXgi1n4KD_w7jJI0uDrF1uNAxmdx9YP_7DMmd5oV6eMFVmG2ja7gFBknVmsjRbGooIPyxs-UOufZYSjF5QZFjY9nYXUS_eI_Zx7bI7zbX2r3KVL-JwV1N-H4Fm1uGc3luIWkxcZ-aEnoOwPTO9-ETgTz1PX7fOXCFdGbNTZzdU2VDMCP8fxqPwQuX4gWc9MgV5kIu4ZVbu_UdSzu6Iksh-1qFOq_pDDatrEr4TcTOgbfY4gAIQHtKh54NltBfvhp2XrmylZVlwnXpC8WPizctE1eK8Gx829Dcn5q01s2qRg5Sep35grvrF-y6zKkPSviJm6qshvRNjz3KMg' failed: HTTP Authentication failed; no valid credentials available
(anonymous) @ signalr.js:5071
(anonymous) @ signalr.js:5052
step @ signalr.js:5013
(anonymous) @ signalr.js:4994
fulfilled @ signalr.js:4985
signalr.js:2150 [2021-06-16T08:08:21.513Z] Error: Failed to start the transport 'WebSockets': Error: There was an error with the transport.
ConsoleLogger.log @ signalr.js:2150
(anonymous) @ signalr.js:4124
step @ signalr.js:3726
(anonymous) @ signalr.js:3707
rejected @ signalr.js:3699
Promise.then (async)
step @ signalr.js:3700
(anonymous) @ signalr.js:3701
__awaiter @ signalr.js:3697
HttpConnection.createTransport @ signalr.js:4070
(anonymous) @ signalr.js:3986
step @ signalr.js:3726
(anonymous) @ signalr.js:3707
fulfilled @ signalr.js:3698
Promise.then (async)
step @ signalr.js:3700
(anonymous) @ signalr.js:3701
__awaiter @ signalr.js:3697
HttpConnection.startInternal @ signalr.js:3917
(anonymous) @ signalr.js:3802
step @ signalr.js:3726
(anonymous) @ signalr.js:3707
(anonymous) @ signalr.js:3701
__awaiter @ signalr.js:3697
HttpConnection.start @ signalr.js:3790
(anonymous) @ signalr.js:2553
step @ signalr.js:2399
(anonymous) @ signalr.js:2380
(anonymous) @ signalr.js:2374
__awaiter @ signalr.js:2370
HubConnection.startInternal @ signalr.js:2541
(anonymous) @ signalr.js:2523
step @ signalr.js:2399
(anonymous) @ signalr.js:2380
(anonymous) @ signalr.js:2374
__awaiter @ signalr.js:2370
HubConnection.startWithStateTransitions @ signalr.js:2510
HubConnection.start @ signalr.js:2506
(anonymous) @ ConnectedDevices:296
signalr.js:2160 [2021-06-16T08:08:21.513Z] Debug: Selecting transport 'ServerSentEvents'.
signalr.js:2160 [2021-06-16T08:08:21.513Z] Debug: Sending negotiation request: http://192.168.0.148:5001/signal-r/devices/negotiate?negotiateVersion=1.
DevTools failed to load source map: Could not load content for http://localhost:50004/js/signalr/dist/browser/signalr.js.map: HTTP error: status code 404, net::ERR_HTTP_RESPONSE_CODE_FAILURE
signalr.js:2160 [2021-06-16T08:08:21.636Z] Trace: (SSE transport) Connecting.
devices:1 GET http://192.168.0.148:5001/signal-r/devices?id=3XUAFbfpkmCMmpWeAbn0oA&access_token=eyJhbGciOiJSUzI1NiIsImtpZCI6IjcwRDkzRDY4M0MzRDZFMEI5ODk3NkZBQTlFNDQyM0REIiwidHlwIjoiYXQrand0In0.eyJuYmYiOjE2MjM4MzA4ODYsImV4cCI6MTYyMzgzNDQ4NiwiaXNzIjoiaHR0cHM6Ly9wYXRhdWdlb2lyZS1hdXRoZW50aWNhdGlvbi5henVyZXdlYnNpdGVzLm5ldCIsImNsaWVudF9pZCI6InJhc3BlcnJ5UGllIiwianRpIjoiM0ZFQzU4RDI4QTI3MDQxQ0Q2QTIzNTE2OUMwMDVBOUMiLCJpYXQiOjE2MjM4MzA4ODYsInNjb3BlIjpbIlNpZ25hbFJqcyJdfQ.XkQMI9CWXgi1n4KD_w7jJI0uDrF1uNAxmdx9YP_7DMmd5oV6eMFVmG2ja7gFBknVmsjRbGooIPyxs-UOufZYSjF5QZFjY9nYXUS_eI_Zx7bI7zbX2r3KVL-JwV1N-H4Fm1uGc3luIWkxcZ-aEnoOwPTO9-ETgTz1PX7fOXCFdGbNTZzdU2VDMCP8fxqPwQuX4gWc9MgV5kIu4ZVbu_UdSzu6Iksh-1qFOq_pDDatrEr4TcTOgbfY4gAIQHtKh54NltBfvhp2XrmylZVlwnXpC8WPizctE1eK8Gx829Dcn5q01s2qRg5Sep35grvrF-y6zKkPSviJm6qshvRNjz3KMg 401 (Unauthorized)
signalr.js:2150 [2021-06-16T08:08:21.675Z] Error: Failed to start the transport 'ServerSentEvents': Error: Error occurred
ConsoleLogger.log @ signalr.js:2150
(anonymous) @ signalr.js:4124
step @ signalr.js:3726
(anonymous) @ signalr.js:3707
rejected @ signalr.js:3699
Promise.then (async)
step @ signalr.js:3700
fulfilled @ signalr.js:3698
Promise.then (async)
step @ signalr.js:3700
rejected @ signalr.js:3699
Promise.then (async)
step @ signalr.js:3700
(anonymous) @ signalr.js:3701
__awaiter @ signalr.js:3697
HttpConnection.createTransport @ signalr.js:4070
(anonymous) @ signalr.js:3986
step @ signalr.js:3726
(anonymous) @ signalr.js:3707
fulfilled @ signalr.js:3698
Promise.then (async)
step @ signalr.js:3700
(anonymous) @ signalr.js:3701
__awaiter @ signalr.js:3697
HttpConnection.startInternal @ signalr.js:3917
(anonymous) @ signalr.js:3802
step @ signalr.js:3726
(anonymous) @ signalr.js:3707
(anonymous) @ signalr.js:3701
__awaiter @ signalr.js:3697
HttpConnection.start @ signalr.js:3790
(anonymous) @ signalr.js:2553
step @ signalr.js:2399
(anonymous) @ signalr.js:2380
(anonymous) @ signalr.js:2374
__awaiter @ signalr.js:2370
HubConnection.startInternal @ signalr.js:2541
(anonymous) @ signalr.js:2523
step @ signalr.js:2399
(anonymous) @ signalr.js:2380
(anonymous) @ signalr.js:2374
__awaiter @ signalr.js:2370
HubConnection.startWithStateTransitions @ signalr.js:2510
HubConnection.start @ signalr.js:2506
(anonymous) @ ConnectedDevices:296
signalr.js:2160 [2021-06-16T08:08:21.675Z] Debug: Selecting transport 'LongPolling'.
signalr.js:2160 [2021-06-16T08:08:21.675Z] Debug: Sending negotiation request: http://192.168.0.148:5001/signal-r/devices/negotiate?negotiateVersion=1.
signalr.js:2160 [2021-06-16T08:08:21.745Z] Trace: (LongPolling transport) Connecting.
signalr.js:2160 [2021-06-16T08:08:21.745Z] Trace: (LongPolling transport) polling: http://192.168.0.148:5001/signal-r/devices?id=cUN1ZArHIZhEi8pQGTK2yw&_=1623830901745.
signalr.js:2160 [2021-06-16T08:08:21.817Z] Trace: (LongPolling transport) polling: http://192.168.0.148:5001/signal-r/devices?id=cUN1ZArHIZhEi8pQGTK2yw&_=1623830901817.
signalr.js:2160 [2021-06-16T08:08:21.817Z] Debug: The HttpConnection connected successfully.
signalr.js:2160 [2021-06-16T08:08:21.817Z] Debug: Sending handshake request.
signalr.js:2160 [2021-06-16T08:08:21.818Z] Trace: (LongPolling transport) sending data. String data of length 32.
signalr.js:2160 [2021-06-16T08:08:21.964Z] Trace: (LongPolling transport) request complete. Response status: 200.
signalr.js:2156 [2021-06-16T08:08:21.965Z] Information: Using HubProtocol 'json'.
signalr.js:2160 [2021-06-16T08:08:21.973Z] Trace: (LongPolling transport) data received. String data of length 3.
signalr.js:2160 [2021-06-16T08:08:21.973Z] Debug: Server handshake complete.
signalr.js:2160 [2021-06-16T08:08:21.973Z] Trace: (LongPolling transport) polling: http://192.168.0.148:5001/signal-r/devices?id=cUN1ZArHIZhEi8pQGTK2yw&_=1623830901973.
signalr.js:2160 [2021-06-16T08:08:21.974Z] Debug: HubConnection connected successfully.
ConnectedDevices:297 signal-r connection established successfully.

You probably aren't grabbing the access token from the query string and passing it to auth. See https://docs.microsoft.com/aspnet/core/signalr/authn-and-authz?view=aspnetcore-5.0#built-in-jwt-authentication for how to do that.

The reason LongPolling works is because it uses a header for the token which works by default with the JWT middleware, unfortunately browsers don't let you set headers so the query string needs to be used, and that needs some additional code to make the JWT middleware work.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM