Nodejs reverse proxy for static files not working with nginx - node.js

I'm trying to setup Angular + Nodejs behind Ngnix on Ubuntu.
Everything is working fine for Angular and Nodejs API but I'm not able to serve static files.
Here is my configuration (/etc/nginx/sites-enabled/default):
location / {
# First attempt to serve request as file, then as directory, then fall back to displaying a 404.
try_files $uri $uri/ /index.html;
}
location /api {
proxy_pass http://localhost:7777;
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;
# preflight requests
if ( $request_method = OPTIONS ) {
add_header "Access-Control-Allow-Origin" *;
add_header "Access-Control-Allow-Credentials" true;
add_header "Access-Control-Allow-Methods" "GET, POST, PUT, HEAD, DELETE, OPTIONS";
add_header "Access-Control-Allow-Headers" "Authorization, Origin, X-Requested-With, Content-Type, Accept";
return 200;
}
}
location /static {
proxy_pass http://localhost:7777;
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;
}
The /api route works fine but /static doesn't.
On local, /static works fine because there is no nginx.
I have following directory structure to serve static files:
public
static
images
css
fonts
https://somewebsite.com/api/read (works fine)
https://localhost:3000/static/images/test.png (works fine)
https://somewebsite.com/static/images/test.png
is not working. What am I doing wrong?

https://localhost:3000/static/images/test.png (works fine) and https://somewebsite.com/static/images/test.png is as expected. According to your configuration, you are also redirecting /static to port 7777: proxy_pass http://localhost:7777;
Changing:
proxy_pass http://localhost:7777;
to:
proxy_pass http://localhost:3000;
should do the trick

I fixed this with following entry:
location /static/ {
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_pass "http://localhost:7777/static/";
# preflight requests
if ( $request_method = OPTIONS ) {
add_header "Access-Control-Allow-Origin" *;
add_header "Access-Control-Allow-Credentials" true;
add_header "Access-Control-Allow-Methods" "GET, POST, PUT, HEAD, DELETE, OPTIONS";
add_header "Access-Control-Allow-Headers" "Authorization, Origin, X-Requested-With, Content-Type, Accept";
return 200;
}
}

Related

Error: Request failed with status code 405 , payload return HTML not JSON like intended

I'm setting up a webapps using Node JS + React + NGINX on AWS
and then when i want to access the url /auth
it return me some HTML code instead of JSON like i wanted to be
i tested the code on LOCALHOST and it works fine
I tried to set the folder permission, because i think maybe user permission is the problem
I also tried editing some stuff on the Nginx.conf
below is my app.conf for the nginx
upstream webapp{
server 127.0.0.1:3018;
}
server_names_hash_bucket_size 64;
server_names_hash_max_size 512;
server {
listen 80 default_server;
listen [::]:80 default_server;
server_name 127.0.0.1;
server_name_in_redirect off;
if ($http_x_forwarded_proto = 'http'){
return 301 https://$host$request_uri;
}
location / {
root /home/website/client/build;
try_files $uri /index.html;
log_not_found off;
access_log off;
}
#error_page 405 =200 $uri;
if ( $http_user_agent ~* (nmap|nikto|wikto|sf|sqlmap|bsqlbf|w3af|acunetix|havij|appscan) ) {
return 403;
}
add_header X-Frame-Options DENY;
add_header X-Content-Type-Options nosniff;
add_header X-XSS-Protection "1; mode=block;";
add_header Strict-Transport-Security "max-age=2592000; includeSubDomains" always;
}
action {…}
​
payload: Object { isAuth: false, error: true }
​
type: "auth_member"
i expect the output code like this one
but instead the web give me something else
you have to define the upstrem location to be proxed to:
# this is an example you can modify the path on as you get it
location /api {
proxy_pass http://webapp;
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;
}

Getting 'The 'Access-Control-Allow-Origin' header contains multiple values' with MEAN and nginx

I have developed an application in MEAN stack and used Nginx for HTTPS.
I have used socket.io and developed rest apis in node.
Below is my Nginx configuration;
server {
# Enable HTTP/2
listen 443 ssl;
listen [::]:443 ssl http2;
server_name api.some.com www.api.some.com;
# Use the Let’s Encrypt certificates
ssl_certificate /etc/letsencrypt/live/api.some.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/api.some.com/privkey.pem;
# Include the SSL configuration from cipherli.st
include snippets/ssl-params.conf;
location / {
if ($request_method = 'OPTIONS') {
add_header 'Access-Control-Allow-Origin' '*';
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
add_header 'Access-Control-Allow-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Content-Range,Range,from,x-auth,Access-Control-Allow-Origin';
add_header 'Access-Control-Max-Age' 1728000;
add_header 'Content-Type' 'text/plain; charset=utf-8';
add_header 'Content-Length' 0;
add_header 'Cache-Control' 'no-cache';
return 204;
}
if ($request_method = 'POST') {
add_header 'Access-Control-Allow-Origin' '*';
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
add_header 'Access-Control-Allow-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Content-Range,Range,from,x-auth,Access-Control-Allow-Origin';
add_header 'Access-Control-Expose-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Content-Range,Range,from,x-auth,Access-Control-Allow-Origin';
add_header 'Cache-Control' 'no-cache';
}
if ($request_method = 'GET') {
add_header 'Access-Control-Allow-Origin' '*';
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
add_header 'Access-Control-Allow-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Content-Range,Range,from,x-auth';
add_header 'Access-Control-Expose-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Content-Range,Range,from,x-auth';
add_header 'Cache-Control' 'no-cache';
}
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-NginX-Proxy true;
proxy_pass http://localhost:5000/;
proxy_ssl_session_reuse off;
proxy_set_header Host $http_host;
proxy_cache_bypass $http_upgrade;
proxy_redirect off;
##### changes for socket.io
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
}
I am getting "The 'Access-Control-Allow-Origin' header contains multiple values" error when my application is attempting to connect socket.
I have found a workout. If I comment the 'add_header' part from the GET section and add the 'Access-Control-Allow-Origin' header from my code then it is working fine. If I don't add the header in my code then the GET rest apis are not working , its asking for the 'Access-Control-Allow-Origin' header.
But I don't want to do that as nginx should handle this, my code should not bother about these headers.
What am I missing?
UPDATE :
I added 'Access-Control-Allow-Origin' in allow headers part of the GET in nginx and removed the GET specific code from node server , the get rest APIs started working BUT the socket started throwing CORS origin error.

nginx and express router get+post request issue

I am trying to setup the 2 node/express sites behind nginx. I think I have tried all possible solutions that I found in the forums, but they only work partially for me.
What I want to achive is:
- one domain with 2 node/express apps
1.) node.dev/site3
2.) node.dev/site4
This works all okay for the main index file, however selecting any button/Route I get a 404 error.
Here is the nginx setup:
server {
listen 80;
root /var/www/node.dev;
server_name node.dev;
index index.htm index.html;
access_log /var/log/nginx/node;
charset utf8;
sendfile off;
location /site3/ {
proxy_pass http://0.0.0.0:8088/;
#rewrite ^/site3/(.*)$ /$1 break;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_cache_bypass $http_upgrade;
}
location /site4/ {
proxy_pass http://0.0.0.0:8080;
#rewrite ^/site4/(.*)$ /$1 break;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_cache_bypass $http_upgrade;
}
}
and this is my Express route setup:
var express = require('express');
module.exports = function(app) {
var router = express.Router();
router.get('/ping', function(req, res){
res.send("pong!", 200);
});
router.get('/walk/:walk_name', function(req, res, next) {
res.send("walk!", 200);
});
router.get('/walk', function(req, res, next) {
res.send("No walker!", 200);
});
router.get('*', function(req, res) {
res.sendfile('./public/index.html'); // load the single view file (angular will handle the page changes on the front-end)
});
app.use('/', router);
}
accessing the site with //node.dev/site3 returns the index file as expected, however clicking on WALK for example, it should return //node.dev/site3/walk, but instead it returns http://node.dev/walk and with that a 404 error.
I can't do any changes in the node/express app. Is there any way to achieve this with the nginx configuration.
Please help. Thanks in advance.
Try setting proxy_pass to 127.0.0.1 not 0.0.0.0. The former means "localhost" the latter means "any host". While you might listen on "any ip", you want to connect to a /specific/ IP.
There may be another issue, but this might help.

Routed traffic with cookies Nginx

first time i'm trying to setup nginx.
I have following problem i would like to solve.
I have two versions of backend v1 and v2.
User is routed to "/v2" (proxy_pass '127.0.0.1:3000;')
Traffic tru "/" (javascript + sockets) has be routed to the same server '127.0.0.1:3000;' by looking at the cookie.
Heres my problem the cookie doesn't exists and therefore 404 will be returned
Any suggestion?
map $cookie_version $site_version {
default "";
"v1" "version=v1;Domain=localhost;Path=/";
"v2" "version=v2;Domain=localhost;Path=/";
}
server {
listen 8081;
server_name localhost;
location / {
if ($cookie_version ~* "v1") {
proxy_pass http://127.0.0.1:8080;
}
if ($cookie_version ~* "v2") {
proxy_pass http://127.0.0.1:3000;
}
}
location /v1 {
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $host;
proxy_http_version 1.1;
set $cookie_version "v1";
add_header Set-Cookie $site_version;
rewrite ^/v1(.*) /$1 break;
proxy_pass http://127.0.0.1:8080;
}
location /v2 {
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $host;
proxy_http_version 1.1;
set $cookie_version "v2";
add_header Set-Cookie $site_version;
rewrite ^/v2(.*) /$1 break;
proxy_pass http://127.0.0.1:3000;
}
}
First of all, read why if is evil http://wiki.nginx.org/IfIsEvil. Use map instead.
My suggestion:
map $cookie_version $mybackend {
default "127.0.0.1:3000";
"v1" "127.0.0.1:8080";
"v2" "127.0.0.1:3000";
}
...
location / {
proxy_pass http://$mybackend;
}
...
location ~ ^/(?<cver>v[12])/ {
...
add_header Set-Cookie "version=$cver;Domain=localhost;Path=/";
rewrite ^/v[12]/(.*)$ /$1 redirect;
}

What MongoDB user role can make POST calls?

I just have created a MongoDB instance on Ubuntu 14.04, with authentication by username:password.
The user I've created is like this:
{
"_id" : "myDatabase.myUser",
"user" : "myUser",
"db" : "myDatabase",
"roles" : [ { "role" : "readWrite", "db" : "myDatabase" } ]
}
And the URI String that I use on my REST API written in Node.js (with Express and Mongoose) is like:
mongodb://myUser:password#localhost:27017/myDatabase
The Connection is OK and the GET methods works fine, but when I use a POST method, like a signup by email/password, the response is:
Status Code:405 Not Allowed
Any idea? Thanks in advance!
FYI: I'm using Nginx as reverse proxy and Web Server for the Frontend (AngularJS app), and the config is:
server {
listen 80;
server_name example.com;
access_log /var/log/nginx/nginx.access.log;
error_log /var/log/nginx/nginx.error.log;
location / {
expires -1;
add_header Pragma "no-cache";
add_header Cache-Control "no-store, no-cache, must-revalidate, post-check=0, pre-check=0";
root /usr/share/www;
try_files $uri $uri/ /index.html =404;
}
location /api/v1 {
proxy_set_header "Access-Control-Allow-Origin";
proxy_set_header "Access-Control-Allow-Methods" "GET, POST, OPTIONS, PUT, DELETE";
proxy_set_header "Access-Control-Allow-Headers" "X-Requested-With,Accept,Content-Type, Origin";
proxy_pass http://127.0.0.1:3000/api/v1;
proxy_buffering on;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header origin "http://example.com";
}
}
I think that it isn't a mongodb restriction. Mongo can't know if the request is POST or GET. Have you verified if the request arrives at nodejs server? I think that nginx is who returns the 405 status code.
It's possible that the failure is due to try to return a static page as response to the POST request. Try adding into nginx.conf file:
# To dispatch static pages on POST request
error_page 405 = 200 $uri;
I have added the following and nginx at least works!:
proxy_redirect off;
The nginx config for default now is:
server {
listen 80;
server_name example.com;
access_log /var/log/nginx/nginx.access.log;
error_log /var/log/nginx/nginx.error.log;
location / {
expires -1;
add_header Pragma "no-cache";
add_header Cache-Control "no-store, no-cache, must-revalidate, post-check=0, pre-check=0";
root /usr/share/www;
try_files $uri $uri/ /index.html =404;
}
location /api/v1 {
proxy_set_header 'Access-Control-Allow-Origin' 'http:/example.com';
proxy_set_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS, PUT, DELETE';
proxy_set_header 'Access-Control-Allow-Headers' 'X-Requested-With,Accept,Content-Type, Origin';
proxy_pass http://127.0.0.1:3000/api/v1;
proxy_redirect off;
proxy_buffering on;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header origin "http://example.com";
}
}
I hope this be valid for somebody.

Resources