Websocket 'Sec-WebSocket-Accept' header mismatch between ReactJS client and Node.js server
NickName:albert Ask DateTime:2019-03-16T09:19:58

Websocket 'Sec-WebSocket-Accept' header mismatch between ReactJS client and Node.js server

I'm writing an application using WebSockets with a React client on port 8080 (run using Webpack devServer) and Node server and sockets on port 5000. However, the initial handshake always fails with an error: WebSocket connection to 'ws://localhost:5000/' failed: Error during WebSocket handshake: Incorrect 'Sec-WebSocket-Accept' header value

To make sure, I check the request and response of the React app using Chrome devtools, and see the following: enter image description here

While on my Node server, I logged the sec-websocket-accept header accept key, as well as the headers for my response, and got the following:

enter image description here

It looks like that indeed, the keys don't match. In fact, they don't seem to be the same keys at all. Is there something in between the React client and Node server (like the Webpack devserver that I'm using for React) that's changing them?

My React code:

    componentDidMount(){
        this.socket = new WebSocket('ws://localhost:5000', ['json']);
        this.socket.onerror = err => {
            console.log(err)
        }
        this.socket.onmessage = e => {
            let res = JSON.parse(e.data);
            console.log(e, res);
            let copyArr = [...this.state.message]
            copyArr.push(res);

            this.setState({
                message: copyArr
            });
        }
    }

My Node.js code:

const server = http.createServer();

server.on('upgrade', (req, socket) => {

    if(req.headers['upgrade'] !== "websocket"){
        socket.end('HTTP/1.1 400 Bad Request');
        return;
    }

    const acceptKey = req.headers['sec-websocket-key'];
    const acceptHash = generateValue(acceptKey);

    console.log('accepkey', acceptKey, 'hash', acceptHash);

    const resHeaders = [ 'HTTP/1.1 101 Web Socket Protocol Handshake', 'Upgrade: WebSocket', 'Connection: Upgrade', `Sec-WebSocket-Accept: ${acceptHash}` ];

    console.log(resHeaders);

    let protocols = req.headers['sec-websocket-protocol'];
    protocols = !protocols ? [] : protocols.split(',').map(name => name.trim());

    if(protocols.includes('json')){
        console.log('json here');
        resHeaders.push(`Sec-WebSocket-Protocol: json`);
    }

    socket.write(resHeaders.join('\r\n') + '\r\n\r\n');
})

function generateValue(key){
    return crypto
      .createHash('sha1')
      .update(key + '258EAFA5-E914–47DA-95CA-C5AB0DC85B11', 'binary')
      .digest('base64');
}

Copyright Notice:Content Author:「albert」,Reproduced under the CC 4.0 BY-SA copyright license with a link to the original source and this disclaimer.
Link to original article:https://stackoverflow.com/questions/55192570/websocket-sec-websocket-accept-header-mismatch-between-reactjs-client-and-node

Answers
ottomeister 2019-03-16T22:33:10

The correct Accept hash for a key of 'S1cb73xifMvqiIpMjvBabg==' is 'R35dUOuC/ldiVp1ZTchRsiHUnvo='.\n\nYour generateValue() function calculates an incorrect hash because it has an incorrect character in the GUID string '258EAFA5-E914–47DA-95CA-C5AB0DC85B11'. If you look very carefully you'll see that the second dash, in '...14–47...', is different from the other dashes. It should be a plain ASCII dash or hyphen with character code 45, but in fact it is a Unicode en-dash with character code 8211. That different character code throws off the calculation.\n\nFixing that character will make your WebSocket client much happier.",


More about “Websocket 'Sec-WebSocket-Accept' header mismatch between ReactJS client and Node.js server” related questions

WebSocket handshake with Ruby and EM::WebSocket::Server

I am trying to create a simple WebSocket connection in JavaScript against my Rails app. I get the following: WebSocket connection to 'ws://localhost:4000/' failed: Error during WebSocket handsha...

Show Detail

WebSocket handshake with Ruby and EM::WebSocket::Server

I am trying to create a simple WebSocket connection in JavaScript against my Rails app. I get the following: WebSocket connection to 'ws://localhost:4000/' failed: Error during WebSocket handsha...

Show Detail

Support WebSocket close reason with a Dart WebSocket server

I'm using Dart's WebSocket classes (both the dart:io and dart:html versions) to connect to a Dart WebSocket server. When I have the client close the web socket connection with a custom close code and

Show Detail

FastAPI WebSocket

I have a background process, which does a file preparation after receiving a file on the endpoint. I have a websocket defined also: @app.websocket_route("/ws/{uid}") async def websocket(

Show Detail

Route websocket client messages to websocket server

I'm trying to ingest data from an external WebSocket using Websocket Client A and send those messages to WebSocket Server B for clients connected to B to view. (Reason being, I'm trying to connect

Show Detail

WebSocket open error: WebSocket error

We are using AppRTCDemo Android for audio/video call https://appr.tc Till last night all is working fine but now we are facing issue WebSocket open error: WebSocket error. WebSocket register error:

Show Detail

Websocket help!

I'm working on a websocket application. I have a server that is written in C#. I have tested it using another C# application for sending and receiving data. The problem occurs when I use a JavaScri...

Show Detail

Starting a websocket in a function (Binance Websocket)

I have been working with binance websocket. Worked well if the start/stop command is in the main programm. Now I wanted to start and stop the socket through a GUI. So I placed the start/stop comman...

Show Detail

websocket-rails: Cannot connect websocket

I must be missing some important information about using websocket-rails, because I can't figure out how to connect to the websocket server. After running websocket_rails:install and following the ...

Show Detail

forward websocket to websocket

I'm using the nginx as reverse proxy for django and React with as config worker_processes 1; events { worker_connections 1024; } http{ server{ include mime.types; default_...

Show Detail