I am trying to allow users to save and download static files. But have the files be accessible only for logged in (authorized) users.
routes/files.js
var express = require('express');
var router = express.Router();
/* Get files */
router.get('/*', isLoggedIn, function(req, res, next) {
console.log('get files called ');
express.static(path.join(__dirname, 'files'));
});
function isLoggedIn(req, res, next){
if(req.isAuthenticated()) return next();
res.redirect('/');
}
module.exports = router;
This works with any get request but not static files. They can be accessed with out being logged in.
app.js
var filesRouter = require('./routes/files');
app.use(express.static(__dirname));
app.use('/files', filesRouter);
I must be missing something simple - Thanks!!
Calling express.static(path.join(__dirname, 'files')); just returns a middleware function. It doesn't actually execute anything more than that. It doesn't serve any files until you call the function that it returns. You could get that middleware function once and then execute it conditionally, but it's easier to just do this:
/* Get files */
router.get('/*', isLoggedIn, express.static(path.join(__dirname, 'files')));
You should use express.static as a middleware.
And then to only allow authenticated users to access files, you coulld register isLoggedIn middleware before it. Please , see the code bellow, this should work.
var express = require('express');
var router = express.Router();
router.use(isLoggedIn); // this must come before express.static
router.use(express.static(path.join(__dirname, 'files')));
/* Get files */
router.get('/*', function(req, res, next) {
console.log('get files called ');
});
function isLoggedIn(req, res, next){
if(req.isAuthenticated()) return next();
res.redirect('/');
}
module.exports = router;
Related
I have some routes under /users that I want to require an authentication token and some that I do not. In order to achieve this I have done the following.
var protected = express.Router();
var unprotected = express.Router();
unprotected.post('/', function(req, res, next) { // A
// no auth required
next();
});
protected.get('/', function(req, res, next) { // B
// auth required
next();
});
module.exports = {
protected: protected,
unprotected: unprotected
};
And then I mount those routes in the following way.
var users = require('./routes/users');
app.use('/users', unprotected_middleware, users.unprotected); // C
app.use('/users', protected_middleware, users.protected); // D
app.use(resultHandler); // Middleware for sending the response (all routes)
app.use(errorHandler); // Middleware for handling errors (all routes)
When I make a POST to /users it runs the expected route, however when next() gets called the protected_middleware runs. This happens because it finds the next /users definition at the line marked with 'D'.
What is the recommended way to get around this?
For each resource I want the ability to have different middleware per route.
POST /users (no auth)
GET /users (requires auth)
DELETE /users/{id} (requires auth and admin access)
You don't need two separate routers here, simply use the middlewares for protected and unprotected where needed (in the router get/post functions):
users.js:
var router = express.Router();
router.post('/', unprotected_middleware,
function(req, res, next) { // A
// no auth required
next();
}
);
router.get('/', protected_middleware,
function(req, res, next) { // B
// auth required
next();
}
);
module.exports = router;
and then:
var users = require('./routes/users');
app.use('/users', users);
app.use(resultHandler); // Middleware for sending the response (all routes)
app.use(errorHandler);
I have trouble implementing route mounting in express.js 4.13.3.
When I first install it, by default created in the app.js
var users = require('./routes/users');//get the "users" route
app.use('/users', users);//mount to "/users"
and the users.js route is like
var express = require('express');
var router = express.Router();
router.get('/', function(req, res) {
res.send('respond with a resource');
});
module.exports = router;
Does not need to define router.get('/users'... because mounting took care of that in the app.js file.
But
When I try to do the same thing
in app.js I set
var upload = require('./routes/upload');
app.get('/upload', upload);//mounting (?)
the upload.js route is
var express = require('express');
var router = express.Router();
router.get('/', function(req, res) {
res.render('upload', {title: 'Photo upload'});
});
module.exports = router;
When I access localhost/users I get 404 error. The only way to fix this , is to define in the upload.js router, this router.get('/upload' instead of this router.get('/'. But that would not be mounting.
The difference I see is that the default code uses app.use('/users', users); and my code uses app.get('/upload', upload);. Is the verb (use/get) the only difference that causes the 404? And if so, why? Or is it something else?
Thanks
You are totally correct that the problem is caused because these to functions work differently. Below are the official API specifications for the functions.
app.use is for mounting a middleware
app.get is for defining (only) one route for a HTTP GET request
This example shows a middleware function mounted on the /user/:id path. The function is executed for any type of HTTP request on the /user/:id path.
app.use('/user/:id', function (req, res, next) {
console.log('Request Type:', req.method);
next();
});
This example shows a route and its handler function (middleware system). The function handles GET requests to the /user/:id path.
app.get('/user/:id', function (req, res, next) {
res.send('USER');
});
I have a simple express app (version 4.9.0) and I am trying to put my middleware in to external files.
My app.js has:
var middleware = require('./lib/middleware');
app.get('/foo', middleware.configcache);
/lib/middleware contains index.js:
exports.configcache = require('./configcache.js');
/lib/middleware/configcache.js contains:
function configcache(req, res, next) {
console.log("hello world");
next();
}
module.exports = configcache;
When I make a GET request to /foo I get a 404. Can anyone advise?
This is how I use it in one of my apps:
app.js:
var routes = require('./routes/index');
routes/index.js:
var express = require('express');
var router = express.Router();
/* GET home page. */
router.get('/', function(req, res) {
res.render('index', {
title: req.i18n.t("meta.title.index")
});
});
module.exports = router;
I scaffolded this express project with the yeoman express generator: yo express
So the answer to your problem is: Don't call next(), but send an actual response to the browser - when you are using router.get():
function configcache(req, res, next) {
res.send(200, 'hello world');
}
or use router.use like described here: http://expressjs.com/guide/using-middleware.html
Please, i need to figure out why the external callback(defined in a diff file) assigned to a route like
app.get('/list', routes.list);
it's working and if I define
var router = express.Router();
router.get('/list', routes.list);
the callback stops to work.
Thanks.
You should apply routes for your application, for example
var routes = {
list: function (req, res, next) {
res.sendFile(path.join(__dirname, './public', 'index.html'));
}
};
// app.get('/list', routes.list);
router.get('/list', routes.list);
// apply the routes to our application
app.use('/', router);
app.listen(3000);
i am trying to execute below code after upgrading express4
// call the Router
var router = express.Router();
router.get('/test1', function(req, res, next) {
// doing more stuff
res.send('test test1 route')
});
// call our router we just created
app.use('/dogs', dogs);
but for some reason i am getting following error
this._router = new Router({
^
TypeError: object is not a function
at Function.app.lazyrouter
can someone help me to solve this problem ,Thank you in advance.
From the documentation:
var app = express();
app.route('/events')
.all(function(req, res, next) {
// runs for all HTTP verbs first
// think of it as route specific middleware!
})
.get(function(req, res, next) {
res.json(...);
})
.post(function(req, res, next) {
// maybe add a new event...
})
So try:
var router = app.route();
router.get('......
Or check the 3 to 4 upgrade guide.
Which says:
app.router has been removed and middleware and routes are executed in
the order they are added. Your code should move any calls to app.use
that came after app.use(app.router) after any routes (HTTP verbs).
app.use(cookieParser());
app.use(bodyParser());
/// .. other middleware .. doesn't matter what
app.get('/' ...);
app.post(...);
// more middleware (executes after routes)
app.use(function(req, res, next);
// error handling middleware
app.use(function(err, req, res, next) {});
I don't have a reputation to comment. Where and how did you declare your dog? Did you mean the following?:
// call the Router
var router = express.Router();
// call our router we just created
app.use(router);
router.get('/test1', function(req, res, next) {
// doing more stuff
res.send('test test1 route')
});
we can use this approach for routing in express4, when i am upgrading to express4 i didn't deleted express 3 folder, i tried deleting express3 folder from node modules and installing express4 than this worked fine