Is there an optional authentication middleware from Passport.js?
Let\'s say I have a route, /api/users
. I want to give just a list of users to the publi
Might be late now, but there's an anonymous
Passport strategy to allow exactly this. That way the public routes can either take authentication or not, but when they do you'll still have all of the information associated with the authenticated user. Check it out here: https://github.com/jaredhanson/passport-anonymous
Here's a simple PoC:
var express = require('express');
var app = express();
var server = app.listen(3012);
var passport = require('passport');
var LocalStrategy = require('passport-local').Strategy;
app.use(passport.initialize());
passport.use(new LocalStrategy(function(username, password, done) {
if (username === 'foo' && password === 'bar') {
return done(null, { username : 'foo' });
}
return done(null, false);
}));
app.get('/api', function(req, res, next) {
passport.authenticate('local', function(err, user, info) {
var data = { hello : 'world' };
// Only if the user authenticated properly do we include secret data.
if (user) {
data.secret = '3133753CR37';
}
return res.send(data);
})(req, res, next);
});
It's calling passport.authenticate
'manually' in the /api
endpoint. That way, you get more control over how to deal with authentication error (which—in your situation—shouldn't be treated as errors but as a way of limiting the output).
Here's the output without proper authentication:
$ curl 'localhost:3012/api?username=foo&password=wrong'
{"hello":"world"}
And here's with:
$ curl 'localhost:3012/api?username=foo&password=bar'
{"hello":"world","secret":"3133753CR37"}
To use as a middleware:
var middleware = function(req, res, next) {
passport.authenticate('local', function(err, user, info) {
req.authenticated = !! user;
next();
})(req, res, next);
};
app.get('/api', middleware, function(req, res, next) {
var data = { hello : 'world' };
if (req.authenticated) {
data.secret = '3133753CR37';
}
return res.send(data);
});