Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cookie-based sticky sessions (reopen) #1159

Closed
turpault opened this issue Sep 28, 2017 · 14 comments
Closed

Cookie-based sticky sessions (reopen) #1159

turpault opened this issue Sep 28, 2017 · 14 comments
Labels
documentation Improvements or additions to documentation

Comments

@turpault
Copy link

turpault commented Sep 28, 2017

Our project is composed of a set of nodejs micro services, communicating through socket.io. Some of those micro services are running behind an amazon ALB load balancer. The only available session stickiness available to ALB target groups is cookie-based and the connections are allocated using a round-robin algorithm when the session cookie is not specified in the http request.

This effectively breaks the handshake protocol occurring when the socket.io connection is established, leading to the dreaded xhr poll error 400 response.

A workaround consists in disabling the xhr polling altogether in the client and only rely on the actual websocket. This is perfect in a controlled environment, but does not work when some of the services are developed and hosted by third parties.

Another hack also exists, which consists in overriding the base require('http').request function call, and issuing a pre-flight request in order to fetch those session cookies. Further http requests would then reinsert the cookies in the request. At best, I call that a hack.

See ALB Sticky Sessions
Another request for the same feature #775

@DaVincii
Copy link

Any updates on this?

@AndyGOBrien
Copy link

anyone ever solve this?

@gabmontes
Copy link

gabmontes commented May 11, 2018

@AndyGOBrien one workaround is to get your cookies from the server first and then open the socket connection specifying the extraHeaders.Cookie option as this:

const socket = io(url, {
  extraHeaders: {
    Cookie: cookiesString
  }
})

Docs: https://github.com/socketio/engine.io-client#nodejs-with-extraheaders

@darrachequesne
Copy link
Member

@turpault there's an io cookie set during the handshake: https://github.com/socketio/engine.io#methods-1

image

@darrachequesne darrachequesne added the documentation Improvements or additions to documentation label May 15, 2018
@AndyGOBrien
Copy link

Yes, i got this to work. Thanks guys

@anderoonies
Copy link

@AndyGOBrien were you doing this in browser or in node? i'm able to get it working in node, but in browser i'm unable to set the cookie header

@59naga
Copy link

59naga commented Aug 16, 2018

socket.io-client-v2.1.1 currently extraHeaders.Cookie option works only on NodeJS

2018-08-17 0 49 07

2018-08-17 0 51 46

at Webpack 3.11.0 / Mac 10.13.6 / Google Chrome 67.0.3396.87

59naga added a commit to 59naga/socket.io-middleware-firebase-admin that referenced this issue Aug 16, 2018
BREAKING CHANGE: socket.io-client\s `extraHeaders` option **works only on nodejs**
socketio/socket.io-client#1159
@Seldonm
Copy link

Seldonm commented Mar 14, 2019

@AndyGOBrien one workaround is to get your cookies from the server first and then open the socket connection specifying the extraHeaders.Cookie option as this:

const socket = io(url, {
  extraHeaders: {
    Cookie: cookiesString
  }
})

Docs: https://github.com/socketio/engine.io-client#nodejs-with-extraheaders

Any working example? Thanks

@cyrusmg
Copy link

cyrusmg commented Oct 1, 2019

Warning: The solution above does not handle AWSALB timeout. If the socket tries to reconnect after stickiness-timeout (i.e. 24hrs), it will throw transport error.

@ceciliazcx
Copy link

socket.io-client-v2.1.1 currently extraHeaders.Cookie option works only on NodeJS

2018-08-17 0 49 07 2018-08-17 0 51 46

at Webpack 3.11.0 / Mac 10.13.6 / Google Chrome 67.0.3396.87

I got same problem. any luck it got fixed already?

@ceciliazcx
Copy link

@Seldonm @gabmontes @59naga any luck that anyone ever get a successful case with extraHeaders?
I am not able to do it at all.

@HighSoftWare96
Copy link

HighSoftWare96 commented Jun 12, 2020

Any update on this? There are load balancer that do work only with Cookie sticky session, like Traefik...

traefik/traefik#1035

@darrachequesne
Copy link
Member

For future readers: cookie-based session affinity is definitely supported

I updated the documentation to make it clearer:

The latter should fix the initial issue with the AWSALB cookie not being sent if the withCredentials is not set to true:

// server
const io = require("socket.io")(httpServer, {
  cors: {
    origin: "https://front-domain.com",
    methods: ["GET", "POST"],
    credentials: true
  }
});

// client
const io = require("socket.io-client");
const socket = io("https://server-domain.com", {
  withCredentials: true
});

@sandeep-svg
Copy link

using

// server
const io = require("socket.io")(httpServer, {
cors: {
origin: "https://front-domain.com",
methods: ["GET", "POST"],
credentials: true
}
});

// client
const io = require("socket.io-client");
const socket = io("https://server-domain.com", {
withCredentials: true
});

it's throwing below error

Failed to load http://localhost:9292/socket-api/?EIO=4&transport=polling&t=OW6kkXe: The value of the 'Access-Control-Allow-Origin' header in the response must not be the wildcard '*' when the request's credentials mode is 'include'. Origin 'http://localhost:3001' is therefore not allowed access. The credentials mode of requests initiated by the XMLHttpRequest is controlled by the withCredentials attribute.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
documentation Improvements or additions to documentation
Projects
None yet
Development

No branches or pull requests