ws icon indicating copy to clipboard operation
ws copied to clipboard

Pass verifyClient result to `connection` event

Open pwnall opened this issue 9 years ago • 72 comments

I'm doing some expensive work in verifyClient and I'd like to reuse the result in the connection event handler.

I'm currently using the fact that the undocumented WebSocket property upgradeReq is the same request as info.req in verifyClient, and I'm modifying the request. This feels dirty though.

Will you please consider allowing any truthy verifyClient result, and passing it into the connection event handler?

If this seems reasonable, I'd be glad to prepare a pull request.

pwnall avatar Oct 16 '14 03:10 pwnall

+1

luin avatar Feb 04 '15 13:02 luin

+1

danturu avatar Feb 08 '16 13:02 danturu

This would be a nice addition. I'm using jwt's in my verifyClient code and it would be nice to cleanly save the decoded result fo use in the connection handler. Something like this:

  const wss = new WebSocketServer({
    server: server,
    verifyClient: function(info, done) {
      let query = url.parse(info.req.url, true).query;
      jwt.verify(query.token, config.jwt.secret, function(err, decoded) {
        if (err) return done(false, 403, 'Not valid token');

        // Saving the decoded JWT on the client would be nice 
        done(true);
      });
    }
  });

  wss.on('connection', ws => {
   // get decoded JWT here?
  });

ChrisZieba avatar Apr 23 '16 20:04 ChrisZieba

@pwnall do you store the jwt as a cookie or do you use it as part of the url?

I'm implementing jwt into my code but I'm not quite sure how to deliver the token.

Any suggestions?

stellanhaglund avatar Jun 03 '16 07:06 stellanhaglund

oh and +1 ;)

stellanhaglund avatar Jun 03 '16 07:06 stellanhaglund

@stefanocudini I'm not using jwt. Here is what I'm doing.

https://github.com/pwnall/w3gram-server/blob/70a3024527e72f184cfb4d0139de218f96690848/src/ws_connection.coffee#L44 https://github.com/pwnall/w3gram-server/blob/70a3024527e72f184cfb4d0139de218f96690848/src/ws_connection.coffee#L58 https://github.com/pwnall/w3gram-server/blob/70a3024527e72f184cfb4d0139de218f96690848/src/ws_connection.coffee#L22

I hope this helps.

pwnall avatar Jun 10 '16 22:06 pwnall

Perhaps #1099 makes this functionality a little more public? Out of curiosity, how are you handling the invalid token on the client side? Using the 1006 error?

dweremeichik avatar Jun 25 '17 23:06 dweremeichik

@ChrisZieba I ended up verifying the JWT in my connection handler as well to get the decoded data. Did you find a better solution?

cjhowedev avatar Oct 18 '17 19:10 cjhowedev

To avoid double JWT encoding, I used global object (pertainInfosThroughConnectionProcess) where I store info’s that I want to retrieve upon opening connection. To distinguish to point right connection as key name I use JWT token itself.


var pertainInfosThroughConnectionProcess = {};

const wss = new WebSocketServer({
  server: server,
  verifyClient: function(info, done) {
    let query = url.parse(info.req.url, true).query;
    jwt.verify(query.token, config.jwt.secret, function(err, decoded) {
      if (err) return done(false, 403, 'Not valid token');

      // Using jwt as key name and storing uid
      pertainInfosThroughConnectionProcess[jwt] = decoded.uid;
      // Using jwt as key name and storing numerous values in object
      pertainInfosThroughConnectionProcess[jwt] = {
        uid: decoded.uid,
        anotherKey: 'another value',
        oneMoreKey: 'one more value'
      };

      done(true);
    });
  }
});

wss.on('connection', ws => {
  // Now we can use uid from global obejct pertainInfosThroughConnectionProcess
  // Note: I used 'sec-websocket-protocol' to send JWT in header, so upon opening connection I can access it with ws.protocol
  var uid = pertainInfosThroughConnectionProcess[ws.protocol];
  // or if you saved numerous values in object
  var uid = pertainInfosThroughConnectionProcess[ws.protocol].uid;
  var anotherKey = pertainInfosThroughConnectionProcess[ws.protocol].anotherKey;
  var oneMoreKey = pertainInfosThroughConnectionProcess[ws.protocol].oneMoreKey;

  // After retrieving data, we can delete this key value as is no longer needed
  // Note: delete is costly operation on object and there is way to optimize it, however for this purpose is not too bad
  delete pertainInfosThroughConnectionProcess[ws.protocol];
});

dmax1 avatar Feb 01 '18 03:02 dmax1

Is there a better way to do it rather than setting up global var?

marcelijanowski avatar Aug 27 '18 09:08 marcelijanowski

@marcelijanowski yep:

verifyClient: function({ req }, done) {
  req.jwt = jwt.verify(
    // ...
  );

  done(true);
});

wss.on('connection', (ws, req) => {
  const jwt = req.jwt;
});

iatsiuk avatar Aug 27 '18 14:08 iatsiuk

I solved this problem using the request object and a WeakMap.

const userRequestMap = new WeakMap();

const server = new ws.Server({
    port,
    verifyClient: (info, done) => {
        const user = authenticateUser(info);
        userRequestMap.set(info.req, user);
        done(user !== null);
    },
});

server.on('connection', (connection, request) =>{
    const user = userRequestMap.get(request);
});

zoltan-mihalyi avatar Sep 11 '18 07:09 zoltan-mihalyi

+1 on this.

I will most likely end up with mutating info.req approach, but it seems fragile and doesn't play well with TypeScript out of the box. It also requires the on('connection', ...) handler to process the second argument which I wouldn't need otherwise (the same concern as in #1099). Instead it would be nice to have some documented way to approach this.

Right now the async verifyClient can invoke the callback with up to 4 arguments in case when result is false, but the truthy case suddenly doesn't care about the other 3 arguments. I'd propose to utilize one of these 3 and have connection object extended with some new property (say, verificationResult), so that whatever the developer passes to the second argument of the callback appears on that new property.

For example,

const server = new ws.Server({
    verifyClient: (info, callback) => {
        const verificationResult = { userId: 123 };
        callback(true, verificationResult);
    },
});

server.on('connection', (connection) =>{
    const { userId } = connection.verificationResult;
});

I'd keep the sync implementation of verifyClient as it is now, because sync computations IMHO either fairly cheep to be repeated inside on('connection', ...) handler or may not be needed there at all. And for those rare cases when the precomputed values may actually be needed, the developer should be able to refactor the code to use the callback instead.

This doesn't seem like a breaking change. Any concerns?

yaroslav-ilin avatar Dec 26 '18 11:12 yaroslav-ilin

@nilfalse that's what i'm looking for !

Are there any plans to implement that feature ? It would definetly help...

dderevjanik avatar Feb 10 '19 15:02 dderevjanik

I would be glad to investigate & contributing this feature. But until any indication from a maintainer, it doesn't make sense to even start implementing it.

yaroslav-ilin avatar Feb 10 '19 17:02 yaroslav-ilin

verifyClient is a technical debt imho and the only reason why WebSocketServer.prototype.handleUpgrade() is async. I would like to remove it completely. Instead of using it, use something like this

const http = require('http');
const WebSocket = require('ws');

const server = http.createServer();
const wss = new WebSocket.Server({ noServer: true });

wss.on('connection', function connection(ws, request, ...args) {
  // ...
});

server.on('upgrade', async function upgrade(request, socket, head) {
  // Do what you normally do in `verifyClient()` here and then use
  // `WebSocketServer.prototype.handleUpgrade()`.
  let args;

  try {
    args = await getDataAsync();
  } catch (e) {
    socket.destroy();
    return;
  }

  wss.handleUpgrade(request, socket, head, function done(ws) {
    wss.emit('connection', ws, request, ...args);
  });
});

server.listen(8080);

It gives the developer a lot of more freedom.

lpinca avatar Feb 10 '19 17:02 lpinca

Anyway, adding custom data to the request object as suggested in some comments above, is ok. It's an established pattern in Express and Koa, for example, to pass data between middleware.

lpinca avatar Feb 10 '19 18:02 lpinca

@lpinca getDataAsync is undefined. What is it doing exactly?

bfailing avatar Feb 12 '19 19:02 bfailing

@bfailing this is the code that you would otherwise have in your verifyClient

yaroslav-ilin avatar Feb 12 '19 19:02 yaroslav-ilin

@bfailing it is undefined because it is an example. getDataAsync is an example function to get some data you may need.

lpinca avatar Feb 12 '19 20:02 lpinca

Guys, thank you very much for all answers :)

@lpinca your answer was especially very helpful... and yes, after implementing it that ways I can understand tech debt behind verifyClient

dderevjanik avatar Feb 18 '19 13:02 dderevjanik

@lpinca this is probably a dumb question, but how do I get the server.on('upgrade', async function upgrade(request, socket, head) to trigger?

I have my server generate a token to authenticate the connection by doing a post first, then the websocket client sends this token along in the initial connection, but I can't seem to trigger the update part

sneels avatar Jul 09 '19 09:07 sneels

@lpinca this is probably a dumb question, but how do I get the server.on('upgrade', async function upgrade(request, socket, head) to trigger?

I have my server generate a token to authenticate the connection by doing a post first, then the websocket client sends this token along in the initial connection, but I can't seem to trigger the update part

The websocket connection is a simple HTTP GET request with an "Upgade: Websocket" header. Look at the sample from @lpinca, the "http server" he creates receives the websocket client connections

netizen-ais avatar Jul 09 '19 11:07 netizen-ais

@lpinca I'm worried that the proposed client auth solution enforces noServer: true and adds boilerplate to the auth process. I currently use an externally defined server and want to continue using it with all of the server options I have configured.

I think something like @nilfalse / @adrianhopebailie's solution would be more clear and reduce boilerplate that everyone wanting to do client auth will eventually need to write.

What is your main concern with something like #1612? Do you think there is an in-between solution that allows sync connections to be made while also allowing a dev to pass custom args into the 'connect' event from verifyClient in an async manner if desired?

One idea is to allow verifyClient to return either a value or a Promise. If verifyClient throws or the resulting Promise throws, then the client is not verified. If it resolves, then that value is passed into connect. This solution obviously ignores the code, name, and headers HTTP response if the verifications fails. I just want to spur additional discussion.

Contrived Async Example

async authenticateUser(info) {
  ...
}

const server = new ws.Server({
    verifyClient: (info) => {
       return authenticateUser(info);
    }
});

Contrived Sync Example

const users = {
  one: 'userOneId',
  two: 'userTwoId',
};

const server = new ws.Server({
    verifyClient: (info) => {
       return users[info.req.headers.user];
    }
});

mgreenw avatar Aug 07 '19 14:08 mgreenw

A good alternative is the one proposed by @zoltan-mihalyi here https://github.com/websockets/ws/issues/377#issuecomment-420169849. Adding stuff to the WebSocket or http.IncomingMessage object should be user decision and not the default (return value of verifyClient).

lpinca avatar Aug 07 '19 17:08 lpinca

@lpinca Thanks for the reply! I agree that the solution proposed by @zoltan-mihalyi is good and fits most use cases. If that is a "supported" solution, then verifyClient should not be deprecated (#1613) as it is the only way to achieve that behavior.

mgreenw avatar Aug 07 '19 17:08 mgreenw

It is not currently deprecated, its use is discouraged. The difference is small but verifyClient is heavily used so it is not going away anytime soon.

lpinca avatar Aug 07 '19 17:08 lpinca

@lpinca Gotcha, that makes complete sense. Thanks for the clarification!

mgreenw avatar Aug 07 '19 19:08 mgreenw

@lpinca how to return error (401, 404, etc.) if the websocket connection is not authorized or the resource is not found, etc.?

Per the ws unit tests, the verifyClient function can be used as follows (for example to return a 404 error). verifyClient: (info, cb) => process.nextTick(cb, false, 404)

How to do this in your example above since there is no response object?

kcwitt avatar Aug 12 '19 15:08 kcwitt

In the same way it is done implicitly by verifyClient. See https://github.com/websockets/ws/blob/fa991731cca990f40ecedb120918d14d08129673/lib/websocket-server.js#L384-L406

This is why in my opinion with the usage suggested above the developer has more freedom. You can literally write whatever you want to the socket.

lpinca avatar Aug 12 '19 15:08 lpinca

@lpinca Thanks!

By the way, do you know why socket.removeListener is called explicitly? I assumed socket would be available for garbage collection after the call to socket.destroy(), including its reference to socketOnError.

kcwitt avatar Aug 12 '19 16:08 kcwitt

It is not strictly needed but it does not harm.

lpinca avatar Aug 12 '19 16:08 lpinca

@lpinca

To make the preferred usage easier, how do you feel about making abortHandshake() part of the public API?

This way those who want to implement custom handshake preprocessing are not forced to re-implement abort logic. Instead, it would look something like this:

server.on('upgrade', async function upgrade(request, socket, head) {
  // Do what you normally do in `verifyClient()` here and then use
  // either `WebSocketServer.prototype.handleUpgrade()` OR 
  // `WebSocketServer.prototype.abortHandshake()
  let args;

  try {
    args = await getDataAsync();
  } catch (e) {
    wss.abortHandshake(socket, 400, "Invalid Request", {"x-custom-header": "foo"});
    return;
  }

  wss.handleUpgrade(request, socket, head, function done(ws) {
    wss.emit('connection', ws, request, ...args);
  });
});

crussell52 avatar Sep 23 '19 21:09 crussell52

@crussell52 I prefer developers to write their own abortHandshake() helper if they have to. It's trivial to do.

lpinca avatar Sep 28 '19 15:09 lpinca

I prefer developers to write their own abortHandshake() helper if they have to. It's trivial to do.

I think "if they have to" is they key phrase. The current recommendation requires developers to do so even if they want the default abort behavior.

I guess it could be argued that they only "need to" if handshakes need to be aborted as part of the custom upgrade handler... But this is being recommended as a replacement for verifyClient() and aborting the handshake seems like a really common aspect of verifying the client 😬. By extension, re-implementing the abortHandshake() behavior becomes very common for those trying to follow the documented recommendations.

Allowing the ability to invoke the default behavior does not prevent developers from implementing their own, but it does reduce the cases that require developers to implement their own.

I realize that I don't know the nuances of this library, so Is there a particular risk to moving the behavior to the public API that I'm missing?

(edited for formatting)

crussell52 avatar Oct 01 '19 18:10 crussell52

The current recommendation requires developers to do so even if they want the default abort behavior.

No, they can just call socket.destroy() if they don't want to write a full HTTP response back to the client. abortHandshake() can be replaced with a single socket.write() call in many cases.

socket.write('HTTP/1.1 400 Bad Request\r\n\r\n');
socket.destroy();

You can write JSON in the body, etc.

lpinca avatar Oct 01 '19 18:10 lpinca

It is still forced reimplementation of existing, proven, tested, and versioned behavior. It seems unfortunate that developers do not have access to invoke the built-in abort behavior. :(

I don't have any more feedback that would further the conversation and I appreciate the energy you put in as a maintainer.

I've already made a near-copy of the default behavior for this project and it is the only WS project I have on my plate right now. For future reference are you open to a pull request that gives developers access to the default abort behavior?

crussell52 avatar Oct 01 '19 21:10 crussell52

It was not designed to be a public API. It's too limiting and hard to use and I prefer to not change it to fit every possible use case. It should be trivial and only handle cases where the request is invalid, like wrong HTTP method, wrong sec-websocket-key header, etc. Specifically

https://github.com/websockets/ws/blob/08c6c8ba70404818f7f4bc23eb5fd0bf9c94c039/lib/websocket-server.js#L208

https://github.com/websockets/ws/blob/08c6c8ba70404818f7f4bc23eb5fd0bf9c94c039/lib/websocket-server.js#L226

Everything else (custom status code, custom status message, custom headers) was added due to verifyClient and it would be great if it could go away with it one day.

http.ServerResponse would give the developer a more user friendly and familiar interface.

const { ServerResponse } = require('http');

const res = new ServerResponse({ httpVersionMajor: 1, httpVersionMinor: 1 });

res.assignSocket(socket);
res.shouldKeepAlive = false;

res.on('finish', function() {
  res.detachSocket(socket); // Not strictly needed.
  socket.destroySoon();
});

res.writeHead(/* ... */);
res.end(/* ... */);

lpinca avatar Oct 02 '19 14:10 lpinca

I understand that verifyClient is deprecated for good reasons, but I also think it would be good to keep a similar high level API. The recommended alternative works but I wouldn't dare to do more than copy pasting your code because things can go horribly wrong there.

I compared both versions:

Using verifyClient

const WebSocket = require('ws');

function getDataAsync() {
  return new Promise((resolve) => setTimeout(resolve.bind(null, 'Hello world'), 500));
}

const wss = new WebSocket.Server({
  port: 8080,
  verifyClient: async (info, done) => {
    let data;
    try {
      data = await getDataAsync();
    } catch (error) {
      done(false, 500, 'internal server error');
      return;
    }

    info.req.data = data;
    done(true);
  },
});

wss.on('connection', (ws, request) => {
  ws.send(request.data);
});

Using the recommended method

const http = require('http');
const WebSocket = require('ws');

function getDataAsync() {
  return new Promise((resolve) => setTimeout(resolve.bind(null, 'Hello world'), 500));
}

const server = http.createServer();
const wss = new WebSocket.Server({ noServer: true });

wss.on('connection', (ws, request, data) => {
  ws.send(data);
});

server.on('upgrade', async (request, socket, head) => {
  let data;

  try {
    data = await getDataAsync();
  } catch (error) {
    const res = new http.ServerResponse({ httpVersionMajor: 1, httpVersionMinor: 1 });

    res.assignSocket(socket);
    res.shouldKeepAlive = false;

    res.on('finish', () => {
      res.detachSocket(socket); // Not strictly needed.
      socket.destroySoon();
    });

    res.writeHead(500, 'internal server error');
    res.end();
    return;
  }

  wss.handleUpgrade(request, socket, head, (ws) => {
    wss.emit('connection', ws, request, data);
  });
});

server.listen(8080);

fungiboletus avatar Nov 04 '19 09:11 fungiboletus

@fungiboletus see https://github.com/websockets/ws/issues/377#issuecomment-537176176.

In your example you are only using res.writeHead() without specifying any headers so you could do something like this:

const http = require('http');
const WebSocket = require('ws');

function getDataAsync() {
  return new Promise((resolve) => setTimeout(resolve.bind(null, 'Hello world'), 500));
}

const server = http.createServer();
const wss = new WebSocket.Server({ noServer: true });

wss.on('connection', (ws, request, data) => {
  ws.send(data);
});

server.on('upgrade', async (request, socket, head) => {
  let data;

  try {
    data = await getDataAsync();
  } catch (error) {
    socket.write(`HTTP/1.1 500 ${http.STATUS_CODES[500]}\r\n\r\n`);
    socket.destroy();
    return;
  }

  wss.handleUpgrade(request, socket, head, (ws) => {
    wss.emit('connection', ws, request, data);
  });
});

server.listen(8080);

which is simpler than the verifyClient version.

lpinca avatar Nov 04 '19 10:11 lpinca

Is there a way to use the recommended approach (verifying the client in the 'upgrade' event handler) when the WebSocket.Server is instantiated with an http server?

ghost avatar Nov 12 '19 19:11 ghost

@jplymale-jt no, because in that case the 'upgrade' listener is added internally.

lpinca avatar Nov 12 '19 19:11 lpinca

I know how to use verifyClient in the backend, what I don't know is how I send the header from the client, I can't find any example to help me.

Someone knows where I find an example code for the client to send headers for verification

eliecer2000 avatar Dec 12 '19 15:12 eliecer2000

I know how to use verifyClient in the backend, what I don't know is how I send the header from the client, I can't find any example to help me.

Someone knows where I find an example code for the client to send headers for verification

I also having this problem

taiho007008 avatar Jan 04 '20 03:01 taiho007008

@lpinca

verifyClient is a technical debt imho and the only reason why WebSocketServer.prototype.handleUpgrade() is async. I would like to remove it completely.

Now that verifyClient is the only reason, could async/sync behaviour depends on there is or not a handleUpgrade callback (which means no verifyClient or verifyClient is sync)? It seems that remove verifyClient option is long time to wait...

const wss = new ( require('ws').Server )({
  noServer: true,
  verifyClient: null,// or sync
});

require('http').createServer().on('upgrade', async (request, socket, head) => {

  // Do what you normally do in `verifyClient()` here and then use `handleUpgrade`.
  try { await getDataAsync(); } catch (e) { return void socket.destroy(); }

  const ws = wss.handleUpgrade(request, socket, head);

  // Directly do things here,
  // which avoided to emit and listen exec on eventEmitter (for cpu),
  // and avoided to create one closure cb function (for memory).

}).listen(8080);;

Or, more simply, add the second argument (request) for the callback:

const wss = new ( require('ws').Server )({ noServer: true });

function onConnection (ws, request, head) { }

require('http').createServer().on('upgrade', (request, socket, head) => {
  wss.handleUpgrade(request, socket, head, onConnection);
}).listen(8080);;

How do you like it?

LongTengDao avatar Mar 17 '20 07:03 LongTengDao

this configuration its working for me, I have a ws client on microcontroller esp32. We most to know the standard ws header dont have Basic authorization so I add it in my ws client library and I recive the request of connection, if its valid acept or refuse. (some old version of browsers you cant use wss://user:pass@hostname:port/path to pass credentials)

const wss = new WebSocket.Server({
    url,
    server: httpsServer,
    perMessageDeflate: false,
    verifyClient: (info, callback) => {
        try {
            var authHeader = info.req.headers.authorization
            console.log(authHeader)
        } catch (error) {
            callback(false,203 ,"lack of authorization")
            return
        }
       var auth = new Buffer(authHeader.split(' ')[1], 'base64').toString().split(':')
       var username = auth[0]
       var password = auth[1]
       console.log("user="+username+" pass="+ password)

       if(username == 'edemone' && password =='secret'){
            callback(true,200,"Come in, We have job to do..")
       }else{
            callback(false,401,"authorization refused")
       }
    },
});

another option its acept the connection wait a second msg on upgrade request and ask fot credentials to continue the connection.

emanavas avatar Jan 26 '21 17:01 emanavas

I know how to use verifyClient in the backend, what I don't know is how I send the header from the client, I can't find any example to help me.

Someone knows where I find an example code for the client to send headers for verification

you can try in this way

node

  server.on('upgrade', async (request, socket) => {
    const protocol = request.headers['sec-websocket-protocol'];

    const user = await jwtVerify(protocol, config.cookie.key);

    if (!user || !user.id) {
      socket.write('HTTP/1.1 401 Unauthorized\r\n\r\n');
      socket.destroy();
      return;
    }
    request.user = user;
  });

in brower

const socket = new WebSocket('ws://localhost:9998',['protocol']);

ckvv avatar Feb 02 '21 07:02 ckvv

I had this same question as @jplymale-jt

Is there a way to use the recommended approach (verifying the client in the 'upgrade' event handler) when the WebSocket.Server is instantiated with an http server?

The answer from @lpinca was the examples in this thread wouldn't work.

@jplymale-jt no, because in that case the 'upgrade' listener is added internally.

Is there some other way to prevent an upgrade if it is instantiated with an http server? I'm trying to prevent upgrade if the origin does not match to prevent CSRF ~(CORS).~

mateuscb avatar Mar 26 '21 03:03 mateuscb

Is there some other way to prevent an upgrade if it is instantiated with an http server? I'm trying to prevent upgrade if the origin does not match (CORS).

https://github.com/websockets/ws/blob/master/doc/ws.md#servershouldhandlerequest.

lpinca avatar Mar 26 '21 06:03 lpinca

I'm trying to prevent upgrade if the origin does not match (CORS).

Hi. I just want to be a bit pedantic and mention that WebSockets do not have CORS. Any website can open WebSocket connections towards other websites. And with CORS it's not up to the server to refuses a connection but to the client. Preventing a WebSocket upgrade if the origin does not match is fine though, it's just not CORS.

fungiboletus avatar Mar 26 '21 06:03 fungiboletus

Taking cue from https://github.com/websockets/ws/issues/377#issuecomment-416248904 I was able to pass decoded JWT token from verifyClient by setting the value into request.headers object and retrieving it in connection event's request object.

I am not sure if this is the right way to do it, but this works.

const { WebSocketServer } = require('ws');

const wss = new WebSocketServer({
  port: 8080, verifyClient: async ({ req }, cb) => {
    const { headers } = req;
    if (headers.token) {
      const decodedToken = await decodeToken(headers.token);
      req.headers.decodedToken = JSON.stringify(decodedToken);
      cb(true);
    } else {
      cb(false, 401, 'Unauthorized');
    }
  }
});


wss.on('connection', (ws, req)=> {
  console.log("on Connection decodedToken ==> ", JSON.parse(req.headers.decodedToken));
});

gladius avatar Dec 18 '21 12:12 gladius

Why not just attach the object to the request with som resonably named property? This is what JS is made for 😃

sdrsdr avatar Dec 18 '21 23:12 sdrsdr

From my socket connection, I'm trying to set a jwt and send it back as an http response, or somehow set the cookie of the client. Am I in the right thread? Is there a recommended method for this?

Esqarrouth avatar Jan 27 '22 19:01 Esqarrouth

From my socket connection, I'm trying to set a jwt and send it back as an http response, or somehow set the cookie of the client. Am I in the right thread? Is there a recommended method for this?

I think this is what headers event is for take a look at https://github.com/websockets/ws/blob/master/lib/websocket-server.js#L387 and line 352. But why go this way if you can just pass the JWT back to the client with a simple message

sdrsdr avatar Jan 31 '22 06:01 sdrsdr

From my socket connection, I'm trying to set a jwt and send it back as an http response, or somehow set the cookie of the client. Am I in the right thread? Is there a recommended method for this?

I think this is what headers event is for take a look at https://github.com/websockets/ws/blob/master/lib/websocket-server.js#L387 and line 352. But why go this way if you can just pass the JWT back to the client with a simple message

@sdrsdr Thank you, I will give it a try. Meanwhile can you explain what you meant by passing JWT back to client with a simple message? What kind of message?

Esqarrouth avatar Jan 31 '22 18:01 Esqarrouth

You create websocket connection to pas messages between peers a browser an a server or two servers. The establishment of the connection folows fixed rules but after that you can send anything you like to your peer, including the JWT token, and the peer can handle it as it's most cinvinient

sdrsdr avatar Feb 01 '22 07:02 sdrsdr

Hi. Sorry, probably stupid question, but It is suggested to use

socket.write("HTTP/1.1 401 Unauthorized\r\n\r\n")
socket.destroy()

It is destroyed, but how to get HTTP/1.1 401 Unauthorized on client?

On server there is simple code.

const ws = new WebSocket("ws://127.0.0.1:8080/")

ws.onerror = (event) => {
  console.log("WebSocket onerror", event)
}

ws.onclose = (event) => {
  console.log("WebSocket onclose", event)
}

Dev console (Network/WS) has Request, but no Response tab

rooton avatar Jul 02 '22 23:07 rooton

@rooton You can find a bunch of examples: Suggested handleUpgrade and connection flow

trasherdk avatar Jul 25 '22 03:07 trasherdk

Hello @trasherdk:

Thanks for the examples.

Out of curiosity, I checked your repo https://github.com/trasherdk/ws and saw that you mention:

This branch is up to date with websockets/ws:master.

Could you please share the motivation for your branch?

Thanks.

farr64 avatar Jul 25 '22 12:07 farr64