Nodebb: Session Mismatch when trying to use separate subdomain for socket.io

Created on 10 Feb 2017  Â·  10Comments  Â·  Source: NodeBB/NodeBB

I get error:

Session Mismatch
It looks like your login session is no longer active, or no longer matches with the server. Please refresh this page.

When I click [OK] it appears again (infinitely).

My server config is:

upstream io_nodes {
ip_hash;
server 127.0.0.1:4567;
server 127.0.0.1:4568;
server 127.0.0.1:4569;
}

server {
server_name example.com;
listen 192.168.100.42;
listen 192.168.100.42:443 ssl;
listen [::];
listen [::]:443 ssl;
ssl_certificate /home/userhomedir/ssl.cert;
ssl_certificate_key /home/userhomedir/ssl.key;
root /home/userhomedir/public_html;
index index.html index.htm index.php;
access_log /var/log/virtualmin/example.com_access_log;
error_log /var/log/virtualmin/example.com_error_log;

if ($scheme = http) {
return 301 https://$server_name$request_uri;
}

#  if ($host ~ ^www\.) {
#     return 301 https://example.com$request_uri;
#  }

proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_set_header X-NginX-Proxy true;
proxy_redirect off;

# https://github.com/NodeBB/NodeBB/issues/4734
proxy_set_header X-Forwarded-Proto $scheme;

# Socket.io Support
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";


gzip            on;
gzip_min_length 1000;
gzip_proxied    off;
gzip_types      text/plain application/xml text/javascript application/javascript application/x-javascript text/css application/json;

location @nodebb {
proxy_pass http://io_nodes;
}

location ~ ^/(images|language|sounds|templates|uploads|vendor|src\/modules|nodebb\.min\.js|stylesheet\.css|admin\.css) {
root /home/usernodebb/nodebb/public;
try_files $uri $uri/ @nodebb;
}

location / {
proxy_pass http://io_nodes;       
}    

} # end of server example.com


server {
server_name live.example.com;
listen 192.168.100.42:443 ssl;
listen [::]:443 ssl;
ssl_certificate /home/userhomedir/ssl.cert;
ssl_certificate_key /home/userhomedir/ssl.key;
access_log /var/log/virtualmin/live.example.com_access_log;
error_log /var/log/virtualmin/live.example.com_error_log;

location / {

proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_set_header X-NginX-Proxy true;
proxy_redirect off;

# https://github.com/NodeBB/NodeBB/issues/4734
proxy_set_header X-Forwarded-Proto $scheme;

# Socket.io Support
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";

gzip            on;
gzip_min_length 1000;
gzip_proxied    off;
gzip_types      text/plain application/xml text/javascript application/javascript application/x-javascript text/css application/json;

proxy_pass http://io_nodes;

} # end of location block

} # end of server live.example.com

My config.json is:

{
    "url": "https://example.com",
    "port": [4567,4568,4569],
    "bind_address": "127.0.0.1",
    "secret": "<hehehe>",
    "database": "mongo",
    "socket.io": {
        "transports": ["websocket", "polling"],
        "address": "live.example.com"
    },
    "mongo": {
        "host": "127.0.0.1",
        "port": "27017",
        "username": "nodebb",
        "password": "<hehehe>",
        "database": "nodebb"
    },
    "redis": {
        "host":"127.0.0.1",
        "port":"6379",
        "password":"<hehehe>",
        "database": 0
    }
}

It is not working the same way also if I change

    "socket.io": {
        "transports": ["websocket", "polling"],
        "address": "live.example.com"
    },

to

    "socket.io": {
        "transports": ["websocket", "polling"],
        "address": "https://live.example.com"
    },

I tried first to visit https://live.example.com first and then https://example.com. This way I don't see the error message. However, when I delete all of the browser cookies and visit https://example.com directly - it shows the same error.

When I visit https://live.example.com/ it did not show the error message, however I don't want visitors to use the subdomain to access the website (because this way caching of images by CloudFlare/Incapsula will not work).

Tried to downgrade socket.io - no effect.

[usernodebb@testserver123 nodebb]$ git rev-parse HEAD
98f2fd62a549d53803110281a9e97584688c973b
[usernodebb@testserver123 nodebb]$ mongod --version
db version v3.4.2
git version: 3f76e40c105fc223b3e5aac3e20dcd026b83b38b
OpenSSL version: OpenSSL 1.0.1e-fips 11 Feb 2013
allocator: tcmalloc
modules: none
build environment:
    distmod: rhel70
    distarch: x86_64
    target_arch: x86_64
[usernodebb@testserver123 nodebb]$ redis- --version
redis-benchmark   redis-check-dump  redis-sentinel    redis-shutdown
redis-check-aof   redis-cli         redis-server      
[usernodebb@testserver123 nodebb]$ redis-server --version
Redis server v=2.8.19 sha=00000000:0 malloc=jemalloc-3.6.0 bits=64 build=c0359e7aa3798aa2
[usernodebb@testserver123 nodebb]$ 
documentation request for comments

Most helpful comment

Tested if with fresh install, only with mongo. Again same error message:

{
    "url": "https://example.com",
    "secret": "<hehehe>",
    "socket.io": {
        "transports": ["websocket", "polling"],
        "address": "https://live.example.com"
    },
    "port": [
        4567,
        4568,
        4569
    ],
    "database": "mongo",
    "mongo": {
        "host": "127.0.0.1",
        "port": "27017",
        "username": "nodebb",
        "password": "<hehehe>",
        "database": "nodebb"
    }
}

When I first visit https://live.example.com and then https://example.com it did not show the error message. After I delete cookies and visit https://example.com it shows the error message again.

All 10 comments

Tested if with fresh install, only with mongo. Again same error message:

{
    "url": "https://example.com",
    "secret": "<hehehe>",
    "socket.io": {
        "transports": ["websocket", "polling"],
        "address": "https://live.example.com"
    },
    "port": [
        4567,
        4568,
        4569
    ],
    "database": "mongo",
    "mongo": {
        "host": "127.0.0.1",
        "port": "27017",
        "username": "nodebb",
        "password": "<hehehe>",
        "database": "nodebb"
    }
}

When I first visit https://live.example.com and then https://example.com it did not show the error message. After I delete cookies and visit https://example.com it shows the error message again.

I noticed that cookie is not set for live.example.com. I added this code (yes, I know it is invalid HTML) into <head> section (via Admin Control Panel):

<img src="https://live.example.com/api/" alt="testing" />

And this annoying message is not displayed (because cookie is written when accessing live.example.com). However, when I login I get the same error message. I need to login through live.example.com in order to get rid of the message when browsing example.com.

I tried with little different nginx.conf:

    server {
        listen 192.168.100.42;
        server_name example.com www.example.com;
        return 301 https://example.com/;
        access_log /var/log/virtualmin/http-example.com_access_log;
        error_log /var/log/virtualmin/http-example.com_error_log;
    } # http example.com

    server {
        server_name example.com;

        listen 192.168.100.42:443 ssl http2;
        ssl_certificate /home/example/ssl.cert;
        ssl_certificate_key /home/example/ssl.key;

        ssl_prefer_server_ciphers on;
        ssl_ciphers ECDH+AESGCM:ECDH+AES256:ECDH+AES128:DH+3DES:!ADH:!AECDH:!MD5;
        ssl_protocols TLSv1 TLSv1.1 TLSv1.2;

        root /home/example/public_html;
        index index.html index.htm index.php;
        access_log /var/log/virtualmin/example.com_access_log;
        error_log /var/log/virtualmin/example.com_error_log;

        location / {
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_set_header X-Forwarded-Proto $scheme;
            proxy_set_header Host $http_host;
            proxy_set_header X-NginX-Proxy true;
            proxy_redirect off;

            # Socket.io Support
            proxy_http_version 1.1;
            proxy_set_header Upgrade $http_upgrade;
            proxy_set_header Connection "upgrade";
            proxy_headers_hash_bucket_size 128;

            proxy_pass http://127.0.0.1:4567;
        }

    } # end of example.com server


    server {
        server_name live.example.com;

        listen 192.168.100.42:443 ssl http2;
        ssl_certificate /home/example/ssl.cert;
        ssl_certificate_key /home/example/ssl.key;

        ssl_prefer_server_ciphers on;
        ssl_ciphers ECDH+AESGCM:ECDH+AES256:ECDH+AES128:DH+3DES:!ADH:!AECDH:!MD5;
        ssl_protocols TLSv1 TLSv1.1 TLSv1.2;

        root /home/example/public_html;
        index index.html index.htm index.php;
        access_log /var/log/virtualmin/live.example.com_access_log;
        error_log /var/log/virtualmin/live.example.com_error_log;

        location / {

        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header Host $http_host;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_set_header X-NginX-Proxy true;
        proxy_redirect off;


        # Socket.io Support
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_headers_hash_bucket_size 128;

        proxy_pass http://127.0.0.1:4567;

        } # end of location block

    } # end of live.example.com server

config.json

```
{
"url": "https://example.com",
"bind_address": "127.0.0.1",
"secret": "",
"database": "mongo",
"port": 4567,
"socket.io": {
"transports": ["websocket", "polling"],
"address": "https://live.example.com"
},
"mongo": {
"host": "127.0.0.1",
"port": "27017",
"username": "nodebb",
"password": "",
"database": "nodebb"
}
}

I tested it with the newest stable Node.js.

[example@testserver123 nodebb]$ node -v
v7.5.0
[example@testserver123 nodebb]$ npm -v
4.1.2
[example@testserver123 nodebb]$ git rev-parse HEAD
98f2fd62a549d53803110281a9e97584688c973b
[example@testserver123 nodebb]$ 

I noticed that only one cookie is set when I access example.com:

When I change the config.json from this:

{
    "url": "https://example.com",
    "secret": "<secret>",
    "socket.io": {
        "transports": ["websocket", "polling"],
        "address": "https://live.example.com"
    },
    "database": "mongo",
    "mongo": {
        "host": "127.0.0.1",
        "port": "27017",
        "username": "nodebb",
        "password": "<hehehe>",
        "database": "nodebb"
    }
}

to this (I am changins address to the same address as url):

{
    "url": "https://example.com",
    "secret": "<secret>",
    "socket.io": {
        "transports": ["websocket", "polling"],
        "address": "https://example.com"
    },
    "database": "mongo",
    "mongo": {
        "host": "127.0.0.1",
        "port": "27017",
        "username": "nodebb",
        "password": "<hehehe>",
        "database": "nodebb"
    }
}

it works, but it creates only one cookie too.

When I remove the socket.io part like this:

{
    "url": "https://example.com",
    "secret": "<secret>",
    "database": "mongo",
    "mongo": {
        "host": "127.0.0.1",
        "port": "27017",
        "username": "nodebb",
        "password": "<hehehe>",
        "database": "nodebb"
    }
}

it creates a second cookie:

It works with this configuration, but I want to use it with websocket on the subdomain.

I noticed that there is no dot before the host name: example.com instead of .example.com:

After I moved "websocket" to the left like this ("pooling" is first) it creates two cookies, but I still see the same error message.

{
    "url": "https://example.com",
    "secret": "<secret>",
    "socket.io": {
        "transports": [ "polling", "websocket"],
        "address": "https://live.example.com"
    },
    "database": "mongo",
    "mongo": {
        "host": "127.0.0.1",
        "port": "27017",
        "username": "nodebb",
        "password": "<password>",
        "database": "nodebb"
    }
}

I made it to work by setting Session cookie domain to .example.com (don't forget the dot at the beginning). Then, I restarted NodeBB and it works.

NodeBB Admin Control Panel → Settings → Cookies → Session cookie domain

Session cookie domain

Now there is a leading dot (.example.com) and it works:

there is a dot before example.com

Instructions how to solve this issue should be added to the error message.

I think this should be either added to the ACP as info text, or to https://docs.nodebb.org

If I understand correctly @vstoykovbg, the cookie is not shared with socket.io leading to the session mismatch errors. That makes sense.

We configure our cookies' domain to be the base url, and that excludes subdomains. As @barisusakli says, a warning in the docs for using websockets on a separate subdomain would be best... this is not a bug in NodeBB itself.

Was this a guide on docs.nodebb.org? or somewhere else...

Was this page helpful?
0 / 5 - 0 ratings

Related issues

darKnight0037 picture darKnight0037  Â·  4Comments

julianlam picture julianlam  Â·  4Comments

tom-rade picture tom-rade  Â·  3Comments

djensen47 picture djensen47  Â·  5Comments

jidanni picture jidanni  Â·  5Comments