9

How to add a cookie value on Socket.IO?

io.sockets.on('connection', function (client)
{ 
    console.log(client.id); 
    client.handshake.headers.cookie.socketID = client.id;   // not work
 // client.handshake.headers.cookie("socketID",client.id);  //crash

    console.log(client.handshake.headers.cookie);
// The current output is:
//connect.sid=tI21xumy3u2n4QXO1GljmPAf.pzFQ1Xu%2B6bz36secu4VSCdSNU8PT1L44gQZ4kFUFQqQ
//this is express session id, and I also want to add client.id of Socket.IO. 

//...........
}

I have read http://www.danielbaulig.de/socket-ioexpress/ , but I do not need session management on node.js, but just need to add a socket.io client ID value in cookie as connect.sid does.

  • https://stackoverflow.com/questions/4754232/can-i-access-a-cookie-from-socket-io/53986892#53986892 – gilbert Dec 31 '18 at 12:38

2 Answers2

12

Take a look at Authorization with Socket.io. This is where it handles the initial connection request, and where you can set a response header.

I'm not sure if the cookie(name,value) shorthand works, though you can try setting it manually:

    var date = new Date();
    date.setTime(date.getTime()+(days*24*60*60*1000)); // set day value to expiry
    var expires = "; expires="+date.toGMTString();

    handshake.headers.cookie = name+"="+value+expires+"; path=/";
Wes Johnson
  • 3,063
  • 23
  • 32
  • Thank you, Wes. I understand Authorization with Socket.io better. However, my concern is, since the block is outside of "io.sockets.on('connection', function (client){......})", it looks not to be able to deal with client.id which I want to include with cookie. Any suggestion about this?? –  May 27 '12 at 20:42
  • I would handle things with client-side code. Ie: emit an event to the client with the socket ID as data and have the client code save down a cookie. You could then read the request cookie in the authorization block on the server side through `handshake.headers.cookie`. I'm not sure why you'd want to do that though, as the socket.id shouldn't be persisted between sessions. On disconnect it's irrelevant. – Wes Johnson May 27 '12 at 21:44
  • I suggested using authorize to save client-specific data as any changes you make to `handshake.headers` on authorization are accessible in `client.handshake` in your main app, as you suggest above. Without more info on your use case, it's hard to get more specific. – Wes Johnson May 27 '12 at 21:46
  • Thanks Wes. Sorry for having let you guess my case. Here is my configuration: A full ajax page on client side that opens popup window that deal with everyauth redirect process. The main page is just static having an opened socket.IO connection. –  May 27 '12 at 21:58
  • http://everyauth.com/ ends up a redirected page after the authorization on the popup window which currently includes Express session ID only. However, since I need to bundle the redirected page with the main full ajax page(no reload, no redirect, has a static socket.IO connection as long as 'app' is opened), I also need to include socket.id(client.id) with cookie. –  May 27 '12 at 22:08
  • wes, I launched more detailed Question here. http://stackoverflow.com/questions/10778149/new-cookie-value-from-socket-io-doesnt-work –  May 28 '12 at 00:23
  • 1
    As you suggested, I found this kind of cookie need to be add from client side, and it works now. Thanks. Add this on the above question page, too. Thanks a lot again! –  May 28 '12 at 01:36
  • If setting up a cookie value this way and checking the browser nothing gets stored. Any idea why? – C4d Mar 24 '17 at 13:41
  • 1
    @C4u this answer was 5 years ago, I believe Socket.io changed the authorization callback to drop the `handshake` prop. See [the docs](https://socket.io/docs/server-api/#namespace-use-fn). Either way, you should use the browser Network devtools to check the initial socket request / response headers to see what's happening with your cookies. – Wes Johnson Mar 27 '17 at 14:23
-4

May seem hacky, I tried all sorts of ways to set a cookie on response to the handshake get request with no success. However, I managed to make it work by tweaking the socket.io prototype code it-self.

In socket.io version 1.3.4,

in \node_modules\socket.io\node_modules\engine.io\lib\server.js

change line 249 from :

headers['Set-Cookie'] = self.cookie + '=' + id;

to

headers['Set-Cookie'] = req.headers.cookie;

all cookies in the request will be returned in the response

JasonY
  • 752
  • 10
  • 24
  • 1
    It is not a great idea to change source code since when you update the version or install the app on another server your changes will be lost. – Yaki Klein Jun 01 '16 at 12:07
  • 1
    this is terrible advice. this will only work until the next `npm install`. – ebr Dec 23 '16 at 08:39
  • At the time of writing this comment there was no other solution – JasonY Jul 26 '17 at 17:23
  • 1
    The only safe way to do this is to fork socket.io, and regularly patch your version from the active project. While, I don't recommend it, you don't deserve a down-vote for suggesting a working hack. – SamGoody Nov 22 '18 at 16:02
  • 4
    just for the argue. he can changed the prototype on run time. so it will be presist over npm install – pery mimon Feb 06 '19 at 08:53