No “Access-Control-Allow-Origin” header is present on the requested resource - node.js

I'm writing a web application using MEAN Stack and I've encountered a problem that I cannot solve, no matter what I try or search.
I'm trying to login using passport/passport-facebook with ExpressJS. If I write in the URL of my browser localhost/api/auth/facebook everything runs fine.
However if I create an element in my HTML code like this Login with Facebook it takes me to my 404 page (see nginx below).
And if I try with the Angular way, like this <button ng-click="login_fb()">Login with Facebook</button>, I get a No 'Access-Control-Allow-Origin' header is present on the requested resource. error.
I believe that I should use the <a href="..."> element but I think my nginx script is blocking it, since I enabled CORS on my NodeJS Server, with this:
server.all('/*', function (req, res, next) {
res.header('Access-Control-Allow-Origin', '*');
res.header('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE,OPTIONS');
res.header("Access-Control-Allow-Headers", "X-Requested-With, Content-Type");
next();
});
I'll leave my nginx script too (ignore the blocks inside '<' and '>'):
worker_processes 4;
events {
worker_connections 1024;
}
http {
upstream backend {
server 127.0.0.1:8080;
}
# To optimize the response of static files
sendfile on;
server {
# Listen to normal port
listen 80;
# Let through files like CSS, JPG, JS, ...
include mime.types;
# Alias for this server
server_name <my-domain>;
# Where the HTML files are located
root <my-folder>;
# Route for API calls
location /api/ {
proxy_pass http://backend;
}
# Route for the index
location ~ ^/*$ {
index index.html index.htm;
}
# Route for 404 page
error_page 404 /index.html;
}
}
EDIT: Using the link like this Login with Facebook but it forces me to use the URL hardcoded and I'll eventually put this app under a domain.
NEW EDIT: I realise that using like this Login with Facebook doesn't work because it thinks it a Angular route, and since I haven't declared in $routeProvider, it takes me to 404.

To avoid the 404, add target="_self" to your link Login with Facebook. It will bypass the angular router.
With the other method, I think you get No 'Access-Control-Allow-Origin' because when you use the angular $http service it's blocked by CORS same-origin policy at the FB API.
You should stick to the link, if you want to do this on the angular end, I recommend this plugin: https://github.com/sahat/satellizer.

Related

How to set proxy pass for react app on nginx?

My react app has got different routes to consume different functionalities
e.x.
localhost:3000,
localhost:3000/Dashboard,
localhost:3000/Hub,
localhost:3000/Person
etc....
I wanted to configure the react app routes in the nginx in the production environment. What I have actually done so far in the nginx configuration at production env is,
server_name api.vesta-project.net;
location /vqcc {
proxy_pass http://localhost:3000/;
}
My problem here is with the current settings, the homepage works well when I say "api.vesta-project.net/vqcc". Whereas, when I click a button that navigates to /Dashboard. I get 404 error as it does not append "vqcc" to the path in the react app internally thus it becomes like api.vesta-project.net/Dashboard" when inspecting the request which is wrong per nginx conf. So I need a solution whenever the client make a request, it should append "vqcc" to the path so that it will become a valid url as per nginx routes.
e.x when client request for api.vesta-project.net/Dashboard, it should become
api.vesta-project.net/vqcc/Dashboard
Pls help me if I can handle this at nginx or package.json without being changing any routes in the react app internally
You can try rewriting the uri in catch-all location.
location / {
rewrite /(.*) /vqcc/$1;
}
location /vqcc{
proxy_pass http://localhost:3000/;
}

Handling redirects in Express to support nginx reverse proxy

I have an express application that is working perfectly on my local environment on port 3001. I need to deploy it on a production server running nginx listening on port 80. Below are some of the express routes
router.get('/', (req, res) => {
//home page, show login page
});
router.post('/login', (req, res) => {
if(errors){
//invalid credentials
return res.redirect('..');
}
//successful login, redirect to admin area
return res.redirect('../admin');
})
and similar routes for authenticated admin users. The routes are not working properly when deployed on nginx using reverse proxy. The nginx reverse proxy settings are as follows:
location /v2manager/ {
proxy_set_header Host $host;
proxy_pass http://127.0.0.1:3001/;
}
I want the application to be accessible on the route v2manager on my production domain like example.com/v2manager. So all the routes become as:
example.com/v2manager/ for the home page
example.com/v2manager/login for login POST route, and
example.com/v2manager/admin for the admin area
However, the redirects are not working properly, on login failure the return res.redirect('..') redirects me to example.com which has a different page whereas it should redirect to example.com/v2manager
I can obviously change my application routes to add v2manager everywhere but the route v2manager can change frequently depending upon our environments and versioning. Also, a solution that would not hamper the local environment so that localhost:3000/login would work always
You need set proxy redirect:
location /v2manager/ {
proxy_set_header Host $host;
proxy_redirect ~/(.*)$ /v2manager/$1;
proxy_pass http://127.0.0.1:3001/;
}

Nginx default page and root webserver directive

I have a small embedded Linux device running Nginx. I can connect to it over the network and access the endpoints on a PC in Chrome or Firefox. My default page contains an HTML tag that points to "loading.jpeg", which is on the device at /tmp/nginx/loading.jpeg. I can type in the browser: http://192.168.0.4/loading.jpeg and see my image. I can also visit the endpoint that renders html and see my image rendered properly.
Now I want to be able to visit the root page: http://192.168.0.4/ in a browser and redirect that to my default page that should render the html and show the image. The problem is that if I set a page for the default "/" location, my webserver root directive pointing to /tmp/nginx no longer works. So I get my page displayed, but the loading.jpeg image is not found. I've tried redirecting the root request to my default page, but that also breaks the webserver root.
How can I render a default webpage for Nginx, while also having my webserver root honored? Thank you.
This does not work ( webserver root is broken - though expected default webpage is shown ):
location / {
default_type text/html;
content_by_lua_file /sbin/http/serve_stream.lua;
## The streaming endpoint
location /streaming {
default_type text/html;
content_by_lua_file /sbin/http/serve_stream.lua;
}
Here is my current nginx.conf without a redirect:
## Setup server to handle URI requests
server {
# Setup the root
root /tmp/nginx;
## Port
listen 80; ## Default HTTP
## Android phones from Ice Cream Sandwich will try and get a response from
server_name
clients3.google.com
clients.l.google.com
connectivitycheck.android.com
apple.com
captive.apple.com;
## We want to allow POSTing URI's with filenames with extensions in them
## and nginx does not have a "NOT MATCH" location rule - so we catch all
## and then selectively disable ones we don't want and proxy pass the rest
location / {
# For Android - Captive Portal
location /generate_204 {
return 204;
}
# For iOS - CaptivePortal
if ($http_user_agent ~* (CaptiveNetworkSupport) ) {
return 200;
}
## Raw WebSocket
location /ws {
lua_socket_log_errors off;
lua_check_client_abort on;
default_type text/html;
content_by_lua_file /sbin/http/websocket.lua;
}
## The streaming endpoint
location /streaming {
default_type text/html;
content_by_lua_file /sbin/http/serve_stream.lua;
}
## We can have file extensions in POSTing of /blahendpoints for filesystem
## control HTTP commands
location ~ "\.(txt|bin)$" {
...
}
}
}
There are a number of solutions. An exact match location block with a rewrite ... last is quite efficient:
location = / {
rewrite ^ /some.html last;
}
See this document for more.

nginx proxy to remote node.js express app in subdirectory

I am completely stuck with a situation where I want to have several node applications on one server. I get this working fine by having the applications running on different ports. I can access the applications by putting in the ip address with port.
I would like to proxy the applications from my nginx server by using different sub-directories like so:
my.domain
location /app1 {
proxy_pass http://10.131.6.181:3001;
}
location /app2 {
proxy_pass http://10.131.6.181:3002;
}
Doing this I had to move the all the express routes to /app1 for application1. This works but now I am stuck with the static files.
I can now access the application with http://10.131.6.181:3001/app1 which is great, but via http://my.domain/app1 the static files are not loaded.
The static files can be accessed directly http://10.131.6.181:3001/css but not via the proxy http://my.domain/css
Ideally I would like to have the applications on different ports without the sub-directory in the express routes but only sub-directories in the proxy. I tried to put my head through the wall for the last 5 hours but didn't achieve anything.
Now I would happy if can at least get the static files via the nginx proxy.
An updated answer for anyone who needs:
instead of
location /app1 {
proxy_pass http://10.131.6.181:3001/app1;
}
use
location /app1/ {
proxy_pass http://10.131.6.181:3001/;
}
or if on local
location /app1/ {
proxy_pass http://localhost:3000/;
}
This is the correct way and this way you will not need to modify express. Express will receive only the part after /app1/
I finally worked it out after a google surge.
I added the directories to the nginx proxy_pass
my.domain
location /app1 {
proxy_pass http://10.131.6.181:3001/app1;
}
location /app2 {
proxy_pass http://10.131.6.181:3002/app2;
}
And I had to change the express applications to use the subdirectory
app.use('/app1', express.static(path.join(__dirname, 'public')));
app.use('/app1'', require('./routes'));
In the router I had to prefix all the redirects.
router.get('/logout', function (req, res) {
req.logout();
res.redirect('/app1/login');
});
The static files are called like so from html
<link rel="stylesheet" href="/app1/css/style.css"/>
A bit of a pain to change all the redirects and static url. I am sure there is a smarter way by setting a global variable in my node-express app. If anybody knows an easier way please post...

getting a 500 internl server error with nginx?

i have installed nginx on my ubuntu ec2 instance and im building an app using node.js, and when i go my amazon url i.e.
http://elastic.ip.address
it works fine, so its running the / file:
app.get('/', function(req, res) {
return res.render('home');
});
however when i try go to http://elastic.ip.address/page2:
app.get('/page2', function(req, res) {
return res.render('page2');
});
I get the 500 internal server error, so i really don't know whats happening, this works on my localhost without running nginx, but not my ec2.
this is my nginx configuration file layout:
server {
listen 80;
root /home/ubuntu/project/;
server_name static_ip.compute-1.amazonaws.com;
location / {
# First attempt to serve request as file, then
# as directory, then fall back to index.html
try_files $uri $uri/ /index.html;
# Uncomment to enable naxsi on this location
# include /etc/nginx/naxsi.rules
proxy_pass http://127.0.0.1:8124/;
}
A couple things to try:
Have a look at /var/log/nginx/error.log and see if you can get some better information about what's going wrong.
Make sure that the user that nginx is running as has read permissions to /home/ubuntu/project/.

Resources