I can't figure out how to use app.all to act as oauth authorization filter for all the routes starting with /api/
passport.authenticate('bearer', { session: false });
is used for authorization. and here are two standard get configurations:
app.get('/api/foo', foo.find);
app.get('/api/bar', bar.find);
I don't want to include it in every call like:
app.get('/api/foo', passport.authenticate('bearer', { session: false }), foo.find);
It's simple, just get it to catch all routes starting with api. Make sure you put this before your routes.
app.all('/api/*', passport.authenticate('bearer', {session: false});
Related
I'm working an API endpoint with expressjs and protecting it with passportjs (using jwt strategy)
I have
passport.use(new JwtStrategy({...})) // Register stratrgy
router.post('/login', (req, res) => {} ) // Generates jwt token
app.use('/api', passport.authenticate('jwt', { session: false }));
app.user('/api', router) // Register the route to /api
If I put /login out of /api, this works just fine. But I want to have some resource like /login in the same root path (/api) to be not protected.
I can go ahead and add passport.authenticate('jwt', { session: false }) to every route registration except the unprotected once, but I don't like that.
I can also create a middleware that call passport.authenticate manually and check other things, but I would like to avoid re-inventing the wheel if it is already done.
Have you tried creating a route like:
app.post('/api/login')
And then after that you define your router like:
app.user('/api', router) // Register the route to /api
Finally inside your router file, at the top, you do
router.use(passport.authenticate('jwt', { session: false }))
I am creating a web application based on Node.js and Express 4. I am also using Passportjs and Google OAuth 2 Startegy for authentication.
I am trying to configure my routes in order to process requests.
I have learned that this line work well:
router.get('/signin/google/callback', passport.authenticate('google', {failureRedirect: '/signin'}));
but when I decided to handle the route in the function, application stopped responding:
router.get('/signin/google/callback', function (req, res) {
passport.authenticate('google', {failureRedirect: '/signin'});
});
Do I miss something? thanks in advance
The callback of the Google OAuth function should be something like this:
app.get('/auth/google/callback',
passport.authenticate('google', { failureRedirect: '/login' }),
function(req, res) {
res.redirect('/');
});
The passport.authenticate() is middleware with arguments request,response, next. You could also define your own middlewares or the last request handler.
My routes.js file
module.exports = function(app) {
//donesn't need to be authorized
app.use('/login', require('./controllers/session'))
//will need to be protected
app.use('/user', auth, require('./controllers/users'))
app.use('/vineyards', auth, require('./controllers/vineyard'))
app.use('/varietals', require('./controllers/varietals'))
app.use('/wines', auth, require('./controllers/wine'))
app.use('/spectrums', auth, require('./controllers/spectrum'))
app.use('/lockers', auth, require('./controllers/locker'))
app.use('/logout', auth, require('./controllers/session'))
}
The 'auth' middleware works when I make a get, or jsonp request, but if I use post it errors out, with a statusCode of 0, and content 'XMLHttpRequestProgressEvent XMLHttpRequestProgressEvent'. However if I go in the actual controllers and put the auth middleware on the actual post like below, it works.
router.post('/', auth, function(req, res) {});
Why is that? Is there a better way to make the middleware run before all calls to a controller then putting it on each individual route?
I'm building an API with Node.js, and I have some endpoints I want to secure.
For simplicity let's assume I'm using HTTP basic authentication (passport-http) for all of my endpoints.
What I'd like to do on top of that, is to make sure that a route like this: api.example.com/users/:uid/ is only accessible by a user with that ID.
I can do it with something like this:
app.get('/users/:uid',
passport.authenticate('basic', {
session: false
}),
function (req, res, next) {
if (req.params.uid !== user.id) {
return next(new Error('Unauthorized'));
}
return next();
},
function (req, res, next) {
// do secret stuff
}
);
But I wonder if there's a way to do this without adding additional middleware, by using Passport itself:
app.get('/users/:uid',
passport.authenticate( ??? ),
function (req, res, next) {
// do secret stuff
}
);
Is it possible? If not, is there a better way?
You can try something perhaps like this. General description: authenticate all requests that hit anything under the /users route as requiring authentication. On your specific route, use some middleware that makes sure that the user trying to access the specific route is the one in the route itself via that uid.
function authorizeUser(req, res, next) {
if (req.user.uid !== req.params.uid) next(new Error('Not your profile!'));
next();
}
// Require login for entire /users section
app.use('/users', passport.authenticate('basic', { session: false }));
// Authorize /users/:uid section to one user
app.use('/users/:uid', authorizeUser);
// Nested routes will all be secured by the middleware above.
app.get('/users/:uid', function (req, res) {
// Secret stuff
});
app.get('/users/:uid/foo/bar', function (req, res) {
// Also secret
});
If you're only securing one endpoint, you can just put it all on the same route.
app.post is not documented in expressjs.com. As I understand, the server listens to a url requestion / etc. which then invokes a middleware and a callback. But all this is same in app.get.
What unique value does it provide to express?
PS. There are other questions like Express Framework app.post and app.get, or app.use and app.get (or app.post) node.js express but reading answers to the same does not provide the answer to teh question.
Edit:
The following code provides for invocation of both app.get and app.post on /login request from the browswer. Are both app.get and app.post invoked? (Presumably in the order of appearance. )
app.get('/login', function(req, res){
var username = req.user ? req.user.username : ''; res.render('login', { title: 'authenticate', username: username,
});
message: req.flash('error') });
app.post('/login',
passport.authenticate('local', { failureRedirect: '/login', failureFlash: true }), function(req, res) {
res.redirect('/admin'); });
enter code here
I'd not say it's not documented, but basically it does the same as app.get() does for HTTP GET, but instead only matches HTTP POST requests.
If you don't know what the difference between a POST and a GET is, you can for example take a look here.
As for your sample code, either your get or your post handler is invoked, depending on whether the browser does a post or a get request. Both are never invoked for the same request.