Protecting post routes NodeJS - node.js

I am working on a nodeJS application. So far i've learned you can protect routes with JWT and i've implemented this. The problem is, I am not sure how to protect a route where the user is allowed to post to.
Let's take a register route for example, this route will be used for user registration. I want users to be able to post to this, BUT only from my application. I dont want anyone to just be able to connect to it via postman and post whatever. How do you protect these kind of routes.
Thanks in advance.

You can use CORS middleware to allow only specific clients to access your server https://expressjs.com/en/resources/middleware/cors.html
Example:
var express = require('express')
var cors = require('cors')
var app = express()
var corsOptions = {
origin: 'http://example.com',
}
app.get('/products/:id', cors(corsOptions), function (req, res, next) {
res.json({msg: 'This is CORS-enabled for only example.com.'})
})
app.listen(80, function () {
console.log('CORS-enabled web server listening on port 80')
})

Related

Can I get the client IP address in express js api?

I'm trying to make a chat app using node.js as backend, where every client has a specific IP so I need to get the IP of the client using my api.
You can use a middleware express-ip
const express = require('express');
const app = express();
const expressIp = require('express-ip');
app.use(expressIp().getIpInfoMiddleware);
app.get('/', function (req, res) {
console.log(req.ipInfo);
});
you can get the variable from req object req.connection.remoteAddress
app.get('/', function (req, res) {
console.log(req.connection.remoteAddress);
});

CSRF-protection for routes of proxied requests in express.js

I'm using http-proxy-middleware (and open to suggestions, but would like to stick to the modules which are proxying requests instead of creating new ones like request or http) to proxy requests to remote host.
Two problems I'm not seeing solutions to currenty:
1) I have a CSRF-protected form (via csurf). I would like it that the middleware checks the CSRF-token first, and in case it is valid only then proxies the request to another host, obtains the response and sends it to user. How to achieve such a setup?
2) http-proxy-middleware (and some other proxying modules) utilizes app.use to set one forwarding rule (append the route to the host), however I would like to have a more fine-grained control over routes - each of my routes must have its own endpoint on the remote host.
The code:
const express = require('express')
const csrf = require('csurf')
const cookieParser = require('cookie-parser')
const proxy = require('http-proxy-middleware')
var app = express()
var csrfProtection = csrf({ cookie: true })
app.use(cookieParser())
// not quite what I need, since different
// routes would utilize different endpoints
app.use('/api', proxy('http://example.com'))
app.get('/forms', (req, res) => {
res.send(
res.render('csrf-protected-forms.html', { csrfToken: req.csrfToken() })
)
})
app.post('/api/one', csrfProtection, (req, res) => {
response = // proxies to 'http://example.com/something/one'
// and obtains response
res.send(response)
})
app.post('/api/two', csrfProtection, (req, res) => {
response = // proxies to 'http://example.com/somethingelse/and/here/two'
// and obtains response
res.send(response)
})
app.listen(3000)
In your code csrf protection runs after proxied middleware. In case if you want protect only this two routes '/api/one','/api/two':
app.use(['/api/one','/api/two'], csrfProtection, proxy('http://example.com'))
app.use('/api', proxy('http://example.com'))
Or if you want protect all POST requests to API, you need somthing this:
app.use('/api', csrfProtection, proxy('http://example.com'))

Third party redirects to browser, not backend

Hello and thank you in advance.
We are running our Node.js/Express application in App Engine which serves a React front end as static files. At one point the user is able to redirect to a third-party so that the user can sign in and authorize some of their data which is managed by that third-party. We provide the redirect URI to the third-party as a parameter in the querystring, which is https://www.example.com/api/thirdparty/OAuthCallback.
When the user submits the authorization on the third-party side, they should be redirected to that URI, which is an API endpoint in our application where we process the result, and then in our backend we redirect the user to their dashboard. Instead, the user gets redirected to that URI in the browser.
We know (we think) we are doing the routing correctly because we are able to hit that end point from Postman and simulate the process that way.
The question is, why is this redirection going to the browser and not our backend?
Below you will find our server entry point (index.js) along with the route we expect to hit (thirdparty.js)
index.js:
//index.js
import express from "express";
import thirdparty from "./routes/thirdparty";
import httpsRedirect from "./middlewares/https-redirect";
const app = express();
var httpsPort = app.get('https-port');
app.use(httpsRedirect({httpsPort: httpsPort}));
app.set('trust proxy', true);
app.use(bodyParser.json({limit: '50mb'}));
app.use(bodyParser.urlencoded({limit: '50mb', extended: true}));
app.use(express.static(path.join(__dirname, '../build')));
app.use("/api/thirdparty", thirdparty);
app.get("/*", (req, res, next) => {
console.log('new request from: '+req);
res.sendFile(path.join(__dirname, '../build', 'index.html'));
});
app.listen(8080, ()=>console.log('Listening on port 8080'));
thirdparty.js (route):
// thirdparty.js
import express from "express";
const router = express.Router();
var oauth2 = require('./lib/OAuth2.0')();
router.get('/OAuthCallback', function (req, res) {
console.log("CODE--------------------------- : " + req.query.code);
var params = {
code: req.query.code,
redirect_uri: 'https://www.example.com/api/thirdparty/OAuthCallback'
}
oauth2.authCode.getOAuthToken(params, saveToken);
function saveToken(error, result) {
// do things with the result
res.redirect(process.env.HOST+"/dashboard");
}
});
export default router;

Webpack proxy messing up my routing?

So I'm using webpack for a project on 8080 with a backend on 3000. The proxy seems to work fine, as I can send requests to the backend and access it without issue. However. I need to include this middleware that allows me to have a user load the page, and if they've logged in within a certain amount of time, the initial request they send to the server logs them in automatically.
router.use(function (req, res, next) {
//check token for routes beneath vvvv
})
router.post('/preauth', function (req, res) {
//return user account info if req.token is valid
})
When I try to get to prauth, or even any route before that from the page loaded on 8080 I only touch the middleware and nothing else.
When I do npm run build then try it again from the identical page on 3000, it works as expected.
No, CORS is not enabled and the proxy does not rewrite any url.
Does anyone know if something in my Webpack config might be causing this?
You need install Cors in nodejs:npm install cors, you can try the following below or you see: Nodejs + Vuejs
var express = require('express')
var cors = require('cors')
var app = express()
app.use(cors())
app.get('/products/:id', function (req, res, next) {
res.json({msg: 'This is CORS-enabled for all origins!'})
})
app.listen(80, function () {
console.log('This is a CORS-enabled web server listening on port 80')
})

Express CORS not working

I just started my nodejs express template buy cors is not working.
I used npm install cors --save
here is the file:
var express = require('express');
var cors = require('cors');
var app = express();
app.use(cors());
var corsOptions = {
origin: 'https://example.com/',
optionsSuccessStatus: 200
};
app.get('/', cors(corsOptions), function(req, res, next) {
res.json({ message: 'hooray! welcome to our api!' });
});
app.get('/tt', function(req, res, next) {
res.json({ message: 'hooray! welcome to our api!' });
});
var port = process.env.PORT || 3030;
app.listen(port);
console.log('Magic happens on port ' + port);
Now with the above code when I access localhost:3030/tt or / I still see the content and I shouldn't
What's wrong with this.. I just lost like 2 hours working on this.. :(
At this time I would like not to use CORS, but in near future when my app is finished, I want to allow incoming calls only from my project, since this app will be my API.
The behavior you are describing seems is what I would expect.
CORS won't help you filter out incoming calls on the server. In this case the browser's CORS check won't kick-in as it appears you are directly typing in the URL in the browser. Browser does a CORS check only when the the webpage loaded from a particular domain tries to access/submit to a URL in a different domain.
A different way to think about CORS. CORS is intended to protect the user sitting in front of the browser, and not the server-code that is being accessed.

Resources