ahwayakchih / openshift-nodebb

**CLOSED** HOWTO install NodeBB in the OpenShift cloud.
17 stars 9 forks source link

Socket.io error when using domain name #7

Closed Benderwan closed 8 years ago

Benderwan commented 9 years ago

Hello,

I have a nodebb forum using this cartridge running on one of my domains but when using Openshift domain name, Socket.io cookies are not set. I can access and use via the new domain name if I visited with the base url (http://nodebb-username...) and the IO cookie is still active, but if I empty cookies, it won't be able to create cookie by itself and will require me to go back to the base url for the cookie to be set.

Sorry if I made any mistakes in my English :smile:

Thank you

ahwayakchih commented 9 years ago

Hi,

Thanks for the report. I'm sorry, but i'm not sure which cookies you write about. express.sid cookie?

I noticed that setting NodeBB secret was missing in deployment script. It should be set to default when installation is run, but maybe something did not work. So now, deployment script generates secret and passes it to NodeBB.

Let me know if that helps. If not, can you explain, which cookies are missing? Or maybe example paths to follow to repeat the problem, for example:

  1. go to forum page and login
  2. go to topic view
  3. clear cookies
  4. go to some other page (but not the main page)
  5. observe cookie name

No worry about mistakes, i'm the last person to criticize - i make them all the time :).

Benderwan commented 9 years ago

Well, the cookie name as shown in Chrome is "io", as the express cookie is set correctly even when accessing through the new domain name.

Here is a screenshot of data as shown when viewing the website with the domain name set
https://dl.dropboxusercontent.com/s/let03a7r9xba0ox/Screenshot%202015-08-19%2010.17.08.png?dl=0

As you can see, IO is not being set by the new domain but only by the old. I will try your manip tonight and will give any update :)

ahwayakchih commented 9 years ago

OK, so it is something different than i thought - latest commits will not fix that.

Do you mean that it's the same installation, i.e., the same OpenShift instance (a.k.a., gear), but accessed through different domains? I did not try to setup custom domain name (alias) on OpenShift account before, but i suspect that NodeBB sets up cookies for configured domain, not for the one it is accessed with.

I thought that OPENSHIFT_APP_DNS_ALIAS environment variable is set by default, but it looks like it is not. Could you try running following command for your application and let me know if that helps?

rhc set-env OPENSHIFT_APP_DNS_ALIAS=yourdomain.example.com -a nodebb

where:

and restart application by running:

rhc app restart nodebb

(again, nodebb is the name of your application).

Benderwan commented 9 years ago

Yes, it is the same gear :)

I just tried your manipulations, I emptied my cookies and when trying to login through the new domain name, when pressing the form submit button, I get a Forbidden error message (Coming from Nodebb and shown as a modal, 403 code), and get the same error message from my old domain name (I am no longer able to access my control panel, but I can delete cartridge and create a new one without any loss of significant data).

EDIT : A few precisions

When on the Login page, XHR-Polling are refused by chrome with this error flag : net::ERR_INSECURE_RESPONSE The Ajax submitting the form is returning 403 forbidden from this URL http://nodebb-titouan.rhcloud.com/login (Where titouan is my username)

ahwayakchih commented 9 years ago

Thanks for the update :).

OK, insecure response is most probably caused by self-signed certificate (or missing certificate). Now, does that show up when you access the site through your custom domain or default (rhcloud.com subdomain)?

Benderwan commented 9 years ago

Well, it occurs on both because requests from both domains are all fired to unisyl.tk (Which is my custom domain), even when the browser URL matches my default domain name. By the way, when firing the same request with a proper URL, I get a response as normal.

ahwayakchih commented 9 years ago

Hi,

Sorry for slow response, i have a lot of work lately.

I did a quick test. I did add custom domain and, as you described, got errors about insecure response. It looks like it keeps calling custom domain, even when site is accessed through default domain.

Good news is that, as i suspected, it is about SSL certificate. If you do not have one for your custom domain, you may need to disable secure websockets (not advised for production). Unfortunately i did not manage to make it simple config switch yet, so you will have to edit JS file for that.

Please test it and let me know if that helped (it did work for me).

Open openshift-app.js file (it should be in your nodebb directory, the one created for your app by rhc command) in your text editor of choice. Find lines 26 to 30 (https://github.com/ahwayakchih/openshift-nodebb/blob/7d3cb6fc5fb425f1c03f64bbf9544762a831a831/openshift-app.js#L26), they should look like this:

        config.url = 'https://' + FQDN;

        // OpenShift supports websockets but only on ports 8000 and 8443
        config['socket.io'] = config['socket.io'] || {};
        config['socket.io'].address = 'wss://' + FQDN + ':8443';

Change them to:

        config.url = 'https://' + FQDN;

        // OpenShift supports websockets but only on ports 8000 and 8443
        config['socket.io'] = config['socket.io'] || {};
        config['socket.io'].address = 'ws://' + FQDN + ':8000';

Save changes. Commit them to your app repo:

git commit -a -m 'Test custom domain without secure websockets'

and push changes to OpenShift:

git push origin master

That should do it, at least for testing.

UPDATE: instead of removing secure websockets, you can enforce using default address for websockets, like this:

        config.url = 'https://' + FQDN;

        // OpenShift supports websockets but only on ports 8000 and 8443
        config['socket.io'] = config['socket.io'] || {};
        config['socket.io'].address = 'wss://' + process.env.OPENSHIFT_APP_DNS + ':8443';

That will keep using secure websockets, but they will be connected through default OpenShift domain (which has valid SSL certificate).

Benderwan commented 9 years ago

Thank you very much, the problem is resolved :smile:

ahwayakchih commented 9 years ago

Great! Can you write which solution worked? I'm assuming that both adding alias environment variable and one of the changes in openshift-app.js, but i'd like to know for sure :).

Benderwan commented 9 years ago

I tried both and here is what I got : Modifying ENV will break your installation, you won't be able to login. Modifying openshift-app.js will solve problems with insecure response.

ahwayakchih commented 9 years ago

Thanks. That's interesting, adding OPENSHIFT_APP_DNS_ALIAS helped here :(.

Benderwan commented 9 years ago

Didn't you get a Forbidden error when logging in after modifying app ENV ?

ahwayakchih commented 9 years ago

Nope. socket.io did throw errors, but site worked ok. It took a minute or so, before i could access site through my custom domain (there was error from OpenShift meanwhile, but it was about service being down, or something like that).

Benderwan commented 9 years ago

Strange thing, I wasn't able to login after doing so, might have been a mistake when entering command line instructions but the server returned a successful operation. I will try that again and give any updates.

Benderwan commented 9 years ago

I just did this and it had no impact on my installation. Strange

ahwayakchih commented 9 years ago

Maybe something was cached before? Or server did not restart yet fully, and you tried to login without refreshing browser window (but that probably would result in 500 or 404, not 403).

Benderwan commented 9 years ago

Probably, NodeBB often triggers errors when not doing a full refresh (Ctrl+F5) after a refresh or reboot of the bord.

ahwayakchih commented 9 years ago

Hi,

I've just updated README and openshift-app.js with information tested in this issue. Thanks for testing and reports :).

Benderwan commented 8 years ago

Hey !

Just some updates with version 0.8.x, None of these solutions actually work as there is a need for the express.sid cookie also to be set from the openshift app domain, else an error is triggered on the nodebb.js file "Uncaught TypeError: Cannot read property 'settings' of null" (Line 14, Column 11663). I tried pretty much everything and it had no success.

Thank you :smile:

EDIT: I'm gonna retry with all combinations of helpers just in case and will keep this message up to date with my results - And I will test with Cloudflare so this is not a global issue as It might not be encountered with non-cloudflare users

Test 1 : OPENSHIFT_APP_DNS_ALIAS=unisyl.tk only : Websocket error 400 Test 2 : OPENSHIFT_APP_DNS_ALIAS=unisyl.tk and OPENSHIFT_NODEBB_WS_USE_APP_DNS=true : Websocket is stuck at 101 Switching Protocols Test 3 : OPENSHIFT_APP_DNS_ALIAS=unisyl.tk, OPENSHIFT_NODEBB_WS_USE_APP_DNS=true and OPENSHIFT_NODEBB_WS_USE_INSECURE=true : stuck at 101 when over HTTP, blocked by the browser over HTTPS Test 4 : OPENSHIFT_NODEBB_WS_USE_APP_DNS=true and OPENSHIFT_NODEBB_WS_USE_INSECURE=true : stuck at 101 when over HTTP, blocked over HTTPS Test 5 : OPENSHIFT_NODEBB_WS_USE_APP_DNS=true only : 101 Test 6 : OPENSHIFT_NODEBB_WS_USE_INSECURE=true only : 101 & blocked over HTTPS

As 101 is normal for Websockets with chrome, websockets are however sending informations as if i was not logged in thus triggering the above described error (On nodebb.min.js script).

However, all these problems are resolved if I login once from my openshift domain and then access through the new domain name.

Proper rooting would be

╔════════╦════════════════════╦═══════════════════════════╦═════════════════╦════════╗
║        ║                    ║                           ║                 ║        ║
║        ║ Assets, base files ║ https://mydomain.com      ║ express.sid     ║        ║
║        ║                    ║                           ║                 ║        ║
║ Client ╟────────────────────╫───────────────────────────╫─────────────────╢ Server ║
║        ║                    ║                           ║                 ║        ║
║        ║       Sockets      ║ https://myapp.rhcloud.com ║ express.sid, io ║        ║
║        ║                    ║                           ║                 ║        ║
╚════════╩════════════════════╩═══════════════════════════╩═════════════════╩════════╝

Again sorry to reopen this :disappointed:

ahwayakchih commented 8 years ago

Hi, thanks for great report :). I'll try to check this out work on it this week.

ahwayakchih commented 8 years ago

I just tried this again, and it seems to work for me. I removed all cookies, made fresh OpenShift NodeBB install, added domain alias (without opening newly installed forum in a browser), used OPENSHIFT_NODEBB_WS_USE_APP_DNS=true version, opened site in a browser (Chrome) using https://, accepted "unsecure" certificate (because it is for *.rhcloud, not for my domain name), and logged in. I got express.sid cookie for my domain name, and io cookie for rhcloud domain (so no express.sid for rhcoud domain). Pages load ok, admin panel loads ok. Can you write, when you got errors on your installation?

Benderwan commented 8 years ago

Problems occur when you for example try to send a chat message or change your online status. Admin also loads OK but changes made would not be saved

ahwayakchih commented 8 years ago

Thanks, i see it now (strange that NodeBB does not show error when settings cannot be saved :(.

It looks like there's no easy workaround. Since one has to accept custom domain certificate anyway (unless it is signed by accepted authority), then i think there's no point for workarounds here. Just remove both OPENSHIFT_NODEBB_WS_USE_APP_DNS and OPENSHIFT_NODEBB_WS_USE_INSECURE environment variables. That way both html and websockets will come from the same host and browser will get correct cookies.

I will probably change overrides, so instead of those two variables there will be just one, to mark if NodeBB should use "secure" URLs or not (https+wss or http+ws).

Benderwan commented 8 years ago

Okay, I understand that.

But as I am using Cloudflare, which is not allowing websockets from the main domain, would there be an easy way to force Nodebb use ajax and disable websockets ?

Anyway, thank you very much for taking time to answer :smile:

(Just one thing, using cloudflare flexible SSL, you can add SSL support free to any domain, so you won't have to accept an unsigned certificate as there is a certificate signed by Cloudflare for your domain)

ahwayakchih commented 8 years ago

I think that dropping websockets would make NodeBB much less nice to use :). I don't know how to enforce ajax (i think that could be done by somehow overriding socket.io settings), but if you can get certificate for your domain, but installed on OpenShift (so not just through CloudFlare), you could try something like this (but i did not test that):

        // Allow to enforce using insecure websockets as a workaround for custom domain without valid SSL certificate
        if (process.env.OPENSHIFT_NODEBB_WS_USE_INSECURE) {
            config['socket.io'].address = 'ws://' + WSFQDN + ':8000';
        }
        else {
            config['socket.io'].address = 'wss://' + WSFQDN + ':8443';
        }

and replace them with this:

config['socket.io'].address = 'wss://ws.example.com:8443';

(of course change subdomain to whatever you have set before :). That's hardcoded change, just to check if it can work at all. If it will, i will change file to use some environment variable for that.

Commit change to file and push changes to OpenShift.

If i'm not mistaken, that will make possible to access NodeBB through main domain, and use websockets through subdomain. Since cookie will be set for main domain, it should also work for subdomain. Again: i did not test it, so it would be great if you could find time and check if it works :).

Benderwan commented 8 years ago

I'll try that and will tell you if it does fix it in 10 mins :smile:

ahwayakchih commented 8 years ago

Thanks :).

Benderwan commented 8 years ago

As I can't use SSL without going through CloudFlare and as CloudFlare does not allow websockets as of now, the only workaround would be to go through the openshift domain name. But cookies can't be set to be shared between myapp.rhcloud.com and myapp.com, there is no way to do so. Anyway thanks for your help :smile:

ahwayakchih commented 8 years ago

Yeah, without certificate it's going to be hard to workaround. I guess one could try to create some plugin, that would "login" user automatically through OpenShift domain, just after he or she logs in through CloudFlare.

Benderwan commented 8 years ago

Might be a suggestion to do to the Nodebb team, but by the time they would release this, CloudFlare would surely have extended their WebSocket support to pro plans.

ahwayakchih commented 8 years ago

You're probably right. Although, it could be useful to use websockets through a different domain/subdomain anyway, not just in CloudFlare scenario.