Laravel Socket.io Cross-Origin denied - node.js

I'm trying to deploy my laravel app with socket.io and I have everything up and running. Node, redis, etc. but when socket event is fired I get this exact error message.
XMLHttpRequest cannot load http://localhost/socket.io/?EIO=3&transport=polling&t=Lbe2fnV. Cross-origin redirection denied by Cross-Origin Resource Sharing policy.
I have gone into my nginx config file and added the following:
upstream app_yourdomain {
server 127.0.0.1:3000;
keepalive 8;
}
location ~* \.io {
proxy_pass http://localhost:3000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
}
but it doesn't do anything.
How can I get rid of the cross-orgin error?
My biggest success came from this post
NodeJS server on DigitalOcean using socket.io returns connection refused

Try to set the origins property like so.
io.set('origins', 'http://localhost:3000');
You can put in every url you allow to get the request from for example
io.set('origins', 'http://google.com:80');
or allow all
io.set('origins', '*:*');
More about the origin property can be found here

Related

Cannot GET etc with Nginx Reverse Proxy React + Node + PM2

In setting up an Nginx reverse proxy for both a React app and a Node web server, it seems to have broken Express on the backend, although I can tell I'm accessing it in the browser by receiving "Cannot GET XX" messages after adding the second location block soon to follow below (previously the browser was just white when visiting the API endpoints because React Router was trying to grab them).
Here's what the config looks like, where port 3000 is my React app and 4000 is my Express server, both being managed by pm2:
server {
root /var/www/html;
index index.html index.htm index.nginx-debian.html;
server_name www.mywebsite.com; # managed by Certbot
location / {
proxy_pass http://127.0.0.1:3000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
}
location /api/ {
proxy_pass http://127.0.0.1:4000/;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
}
}
Simple Express route that won't work ("Cannot GET /"):
app.get('/', (req, res) => {
res.send('Hello, world!');
});
There is some additional certbot stuff that was generated for SSL, but I'm not sure it's relevant. The React app works perfectly, but whether it's "location /api/" vs "location /api" and no matter how I name my routes in Express, they all can't resolve despite having worked perfectly before. Thanks in advance for any guidance!
EDIT: I changed the server conf to at least map /api/ to my server's root with a trailing backslash so I don't have to prepend /api to every route handler, but the issue still remains ("Cannot GET /").
Why do you use the following headers?
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
Probably not needed if you are using TLS/https and it may be causing issues with express if the upgrade header exists. Try removing that.
These headers are generally used for WebSockets. See the nginx docs for more details.

How to setup nginx for multiple nodejs apps on a server (using socket.io with namespaces)

We have a nodejs app that currently uses socket.io ( with namespaces ). This app is used as a dashboard for a specific financial market. Each instance of app subscribe to a specific market data and provides a dashboard. Initially we were running 3 separate instances of this app configured for 3 separate markets on the server, all binding to separate ports for serving requests.
Since we plan to add more markets it makes sense to have a reverse proxy server where a single port (along with separate URI for each market) can be used. However, setting up nginx has been a nightmare for various reasons.
(a) each instance of app for a market can be in different development stage and hence can have different static files. Managing all static file via nginx seems painful ? What can be done to leave handling of the static files with the app itself.
(b) socket.io communication is a failure. We tried to look into network communication and it seems it keeps on getting 404 page not found error when trying to connect to socket.io server. Not sure why it is connecting via http::/localhost/server.io/ instead of ws://localhost/server.io/ ? Can somebody point us to a similar example ? Anything that needs to be taken care of ?
IN our case we have been trying the following inside nginx sites-available/default
location /app/ {
proxy_pass http://localhost:3000/;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
#proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
# kill cache
add_header Last-Modified $date_gmt;
add_header Cache-Control 'no-store, no-cache, must-revalidate, proxy-revalidate, max-age=0';
if_modified_since off;
expires off;
etag off;
}
Using nginx as a reversed proxy should not give you a hard time. The great thing about nginx is that you can have multiple projects on the same server with different domains.
Here is an example of nginx with multiple projects:
server {
listen 80;
server_name yourdomain.com;
location / {
proxy_pass http://localhost:3000;
#Rember to set the header like this otherwise the socket might not work.
proxy_set_header X-Real-Ip $remote_addr;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
}
}
server {
listen 80;
server_name subdomain.yourdomain.com;
location / {
proxy_pass http://localhost:3001;
}
}
I'm not sure why your socket should fail. Perhaps the mistake is that you try to define the route on the client site. Try having the javascript like this:
var socket = io();
or if your socket runs on one of your other applications:
var socket = io('http://yourdomain.com');
And remember that your changes should be added to sites-enabled instead of sites-avaible

Digitalocean hosted node app 502 Bad Gateway for POST/GET

I have node app hosted on digitalocean.
In file /etc/nginx/sites-available/default I have written
server {
listen 80;
server_name dailymartbasket.in;
location / {
proxy_pass http://127.0.0.1:3000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
}
}
Problem:
When I call my domain name in browser then angular app inside this node app gets loaded which is at / route. from angular app we are making some POST/GET calls to node app but it returns error for those routes
Request URL:http://<domainname>/api/categories
Request Method:GET
Status Code:502 Bad Gateway
Remote Address:<droplet ip>:80
Referrer Policy:no-referrer-when-downgrade
Please suggest what is wrong, I am pretty new to server hosting

nodejs + nginx getting 502 error when using https module instead of http

I have make my nodejs app, hosted it on digital ocean server connect it to domain name, and all works fine, but when i'm trying to put ssl certificate (using https module instead of http), it doesn't works. Here is a code:
var sslopt = {
key : fs.readFileSync('./ssl/server.key'),
cert : fs.readFileSync('./ssl/server.crt'),
ca : [fs.readFileSync('./ssl/ca1.crt'), fs.readFileSync('./ssl/ca2.crt')]
};
var server = https.createServer(sslopt,function(req,res){
...
});
server.listen(8001,function(err){
...
});
My nodejs app running fine but if i'm trying to access it, I just see the 502 Bad Gateway error, and no requests was sent to my nodejs app. When I have opened my nginx error log I see the errors
-date- -time- [error] 18116#18116: *1 recv() failed (104: Connection reset by peer) while reading response header from upstream, client: -ip-, server: -server-, request: "GET / HTTP/1.1", upstream: "http://127.0.0.1:8001/", host: -host-
But the most strange thing that if I'm trying to get access with https protocol and port 8001 (https://{domainname}.com:8001) I can see my app working fine, but connection is not secured.
I just can't understand what I'm doing wrong...
P.S.
my nginx config file
server {
listen *:443;
listen *:80;
server_name {myhostname};
access_log /var/log/nginx/qt.access.log;
error_log /var/log/nginx/qt.error.log;
root /srv/qt;
index index.html index.htm index.php;
# Headers to pass to proxy server.
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $host;
proxy_set_header X-NginX-Proxy true;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_cache_bypass $http_upgrade;
proxy_http_version 1.1;
proxy_redirect off;
# Go to next upstream after if server down.
proxy_next_upstream error timeout http_500 http_502 http_503 http_504;
proxy_connect_timeout 5s;
# Gateway timeout.
proxy_read_timeout 20s;
proxy_send_timeout 20s;
# Buffer settings.
proxy_buffers 8 32k;
proxy_buffer_size 64k;
location / {
proxy_pass http://127.0.0.1:8001;
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
Recognizing that this is an old post, hopefully this will still help someone out. I just figured out what seems to be the same thing and it was proxy server related.
My NodeJS server worked fine without SSL but gave the 502 without ever reaching the server when I used https.
// =============================================================================
// START THE SERVER
var port = process.env.PORT || 8080; // set our port
https.createServer({
key: fs.readFileSync('./certs/private.key'),
cert: fs.readFileSync('./certs/cert.crt')
}, app).listen(port);
//app.listen(port);
console.log('API Active on port ' + port);
My client and server are behind a pfSense firewall using a Squid3 proxy server.
pfSense controls the DNS for api.mydomain.com and routes the traffic to my dev server when I make a call to api.mydomain.com:8080/myroute. I have a valid SSL/TLS cert for api.mydomain.com
With the app.listen(port) line uncommented everything worked great.
With the https.createServer(...) uncommented I got the 502 error and traffic never reached the server.
To fix:
In pfSense click Services -> Squid Proxy Server
Click on the ACLs
configuration page
At the bottom of the page find the section
called Squid Allowed Ports.
In the field For ACL SSL Ports, enter the port your
application is using (in my case 8080).
For me, rainbows appeared and bluebirds did sing.

Socket.io events not received (nginx reverse proxy, server to client)

I have a nodejs socket.io app running under nginx reverse proxy.
My nginx configuration is as follows:
location ~ ^/(online|socket\.io) {
proxy_pass http://localhost:8888;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
}
This seems to work, and my nodejs app picks up the connection fine. On the server side socket.io I have the following:
io.of('/online').on('connection', function(socket){
This seems to work fine, and the 'connection' event is firing
The problem arises when I try to emit an event from the server to the client:
socket.join("users");
io.sockets.in("users").emit("got_users",users);
The 'got_users' event is not being picked up by the client. On the client side I have the following:
a4e.socket=io.connect('http://www.example.com/online');
This seems to work fine, but then:
a4e.socket.on("got_users",function(online_users){
This doesn't pick up the "got_users" event, no matter what I try.
Any help greatly appreciated.
I finally figured this out, the following line:
io.sockets.in("users").emit("got_users",users);
Should be replaced with:
io.of("/online").in("users").emit("got_users",users);
Then it works.

Resources