How protect a RestFul Api in Nodejs? - javascript

Nowadays i am using https://github.com/baugarten/node-restful wich helpme to work in an API, the question is?
I am working in Express framework, are there a way to protect the "GET" request from other site to mine.
I use the CSRF from express but only work by POST,PUT,DELETE methods with a message of FOrbidden 403 when treat make anithing since curl in console but if I make a curl toward a Get method curl localhost:3000/posts that giveme an array with all the posts.
app.use(express.csrf());
app.use(function(req, res, next){
res.locals.token = req.session._csrf;
next();
});
app.use(app.router);
What you advice me? are there other modules to work an Api better? How can protect an Api in nodejs? What are the best practices that a haver to learn?
Thanks by your Help.

Try Express middleware which is designed to do so. For example:
var express = require('express');
var app = express();
// simple middle ware to protect your URI
app.use(function(req, res, next){
if (req.method == 'GET') {
if (!req.locale.token) { res.send(403); } // custom to fit your policy
else if (req.protocol !== "https") {res.redirect("your-secure-url");}
else { next(); }
}
});

Related

Simple NodeJS RESTful API with post method and no database involved

Im very new to nodejs ive used an exmaple to write simple REST app, this is using GET method but im trying to use POST method with --data, for example
curl -X POST --data 'bla' http://localhost:port
i want it to return repsone "blabla"
im trying to see all kinds of exmaple but lots of them using databases and on this simple app i dont want any database involved,
appriciate if anyone can guide me or point me to a good example
**edit
const express = require('express')
const app = express()
app.use(express.json())
app.use(express.urlencoded({
extended: true
}))
app.use((req, res, next) => {
console.log(new Date(), req.url, req.method)
next()
})
app.post('/', (req, res, next) => {
try {
if (req.body.data == 'bla'){
res.send("blabla")
}
} catch (error) {
next(error)
}
})
app.listen(3000)
it works without the "if" part, i must be missing something small here...

How to protect a route with a referrer in Node.js

I am trying to protect a route in my node.js application such that if the user wants to go to the page /post they have to come from /blog. If the user comes from anything other than /blog they are to be redirected to /. I have the following code that uses the http referrer
let ref = req.headers.referer;
if ((ref === undefined) || (!ref.includes('blog'))) {
res.redirect('/')
}
It seems to work well if I console.log for testing but if I do res.redirect, I get the error
Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client.
How can I use the referrer to protect the route.
Should there be any other way of accomplishing this without using referring: all suggestions are welcome.
Thanks in advance
Try this, In your app.js file include this.
const express = require('express');
const app = express();
app.get('/',(req, res, next)=>{
res.send('Ready')
});
app.get('/test',(req, res, next)=>{
res.send('Ready')
});
// Below (*) will consider unwanted urls
app.use('/*', function(req, res, next) {
res.redirect('/')
});
app.listen(4000);
FYI, If you try demo.com/unkownurl will redirect to root like demo.com/

Force redirect heroku/angular app to HTTPS version

I have an angular 5 app which is hosted on heroku. Currently the users can access the HTTP version of the app.
How can I force the users to be redirected to HTTPS version even if they access HTTP?
What I have tried:
app.use(function (req, res, next) {
let sslUrl;
if (process.env.NODE_ENV === 'production' &&
req.headers['x-forwarded-proto'] !== 'https') {
sslUrl = ['https://myapp.herokuapp.com', req.url].join('');
return res.redirect(sslUrl);
}
return next();
});
I have placed the above code in my node.js server but it has not worked.
The users are unable to use the app over HTTP as they get a 403 ERROR
I used the "force-ssl-heroku" package at https://github.com/rangle/force-ssl-heroku, works like magic and very easy integrated.
Just require inside your start entry point script:
var forceSsl = require('force-ssl-heroku');
and use it like that:
app.use(forceSsl);
Deploy and enjoy.

How to post to api from Express.js

I am new to Node/Express and to API's in general. Long story short, I am a front end guy diving into backend and architecture for the first time. The breakdown of my problem is as follows:
App description: A web app that allows users to view medical data records.
Desired feature: Change the state of a json record on page load. When a user opens a record(page), I want to change a json object from UNDIAGNOSED to DIAGNOSED automatically. This needs to be done server side to avoid exposing the api endpoint, which needs to stay hidden for security reasons. Think of it like a 'read/unread' email. Once it has been opened, it changes the state to 'read'
Probelem: ...I am a newb...
//When the server GETs a request to this URL
router.get('/content/:contentid', function(req, res, next) {
// Configure the REST platform call
var platform_options = {
resource: '/content/' + req.params.contentid,
method: 'POST',
json: "diagnosis_state: DIAGNOSED"
};
// Make the call
var platform = ihplatform(_config, req.session, platform_options, callback);
platform.execute();
// Result processing
function callback(error, response, body) {
console.log(response.body);
}
});
I am using a custom HTTP API that was built in-house by another developer. The endpoint for the call is dynamically generated via the re.params.contentid. You will also notice that the call itself is built into the platform.execute function.
There is a bit of copy/pasting going on, as I am trying to modify a working call.
My question is this: How do I make an api POST call to a remote API upon the HTTP request for a certain url via express.js?
Here is what you can do on express.js -
1) write a module for route mappings in a separate js file where all the mappings can be listed. Below is the code snippet of the module file
function mappings(app)
{
var email = require('./routes/emails');// ./routes/emails is js file location exporting UpdateEmail variable which contains function for update
app.put('/email/update', email.UpdateEmail); // mapping url /email/update to exported variable UpdateEmail
}
2) add following statement in app.js file where mapRoutes is a .js file created in step 1
require('./mapRoutes').mappings(app);
3) Below is the sample app.js file
var path = require('path');
var favicon = require('static-favicon');
var logger = require('morgan');
var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser');
var app = express();
// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'jade');
app.use(favicon());
app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded());
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));
app.use('/', routes);
app.use('/users', users);
app.all('*', function(req, res, next) {
res.header('Access-Control-Allow-Origin', req.headers.origin);
res.header('Access-Control-Allow-Methods', 'POST, GET, PUT, DELETE, OPTIONS');
res.header('Access-Control-Allow-Credentials', false);
res.header('Access-Control-Max-Age', '86400');
res.header('Access-Control-Allow-Headers', 'X-Requested-With, X-HTTP-Method-Override, Content-Type, Accept');
next();
});
app.options('*', function(req, res) {
res.send(200);
});
require('./mapRoutes').mappings(app);
/// catch 404 and forwarding to error handler
app.use(function(req, res, next) {
var err = new Error('Not Found');
err.status = 404;
next(err);
});
/// error handlers
// development error handler
// will print stacktrace
if (app.get('env') === 'development') {
app.use(function(err, req, res, next) {
res.status(err.status || 500);
res.render('error', {
message: err.message,
error: err
});
});
}
// production error handler
// no stacktraces leaked to user
app.use(function(err, req, res, next) {
res.status(err.status || 500);
res.render('error', {
message: err.message,
error: {}
});
});
module.exports = app;
4) live website running on above code - kidslaughs.com
I'm not quite sure your question here, because "POSTing from ExpressJS" could mean two different things.
In the most common case, you are making a POST request from a web page. While this might be served or even rendered via Express, the call is originating from the web page. In that case the javascript on the web page is making the post. Common web frameworks for that might be jQuery's $.ajax or Angular's $http. Whatever framework you use, you'll define the data to post, the API endpoint to post to, and what to do with the response.
Another meaning of your question might be that you want your Express app to make a http request from the server side. You will need a package to do so, so that you can make a HTTP programatically. A popular package for this is request.
It's hard to say more without knowing what frameworks you are working with. Keep searching around, you'll figure it out!
I think you're looking for request.js.
var request = require('request');
request.post('/content/' + req.params.contentid').form({json: "diagnosis_state: DIAGNOSED"})

Expressjs rerouting

I need to make routing flexible for slashes, for example
app.get('/home/pages')
router must handle
////home///pages
/home/pages////
etc...
requests.
Currently I have one idea to implement this, but for that I need to know how to reroute request via middleware,
If you can answer this question or suggest something else I will be grateful to you.
Also please don't suggest using regex for defining routers, because project is already done and there is a lot of already defined routes.
You need to rewrite url in a middleware:
var express = require('express');
var app = express();
app.use(function (req, res, next) {
req.url = req.url.replace(/\/+/g, '/');
next();
});
app.get('/home/pages', function (req, res) {
res.send('some pages');
});
app.listen(3000);

Categories