Example for mixing Basic & Local strategies
nestradaOBS opened this issue · 3 comments
Hello,
This is not really an issue but is there a way to mix both Basic HTTP and Local passport strategies? The reason is that I would like to use Basic for easy testing with supertest (using request(app).auth()), and some clients which are totally restful otherwise a simple login form using the Local POST strategy.
In essence, I want to apply a middleware routine using app.use('*', ensureAuthenticated, ...), where ensureAuthenticated checks if the session exists and is authenticated or the http credentials are provided).
The other examples of mixing twitter, oath and other passport strategies does not really apply since they are all based on mapping disctinct routes whereas stateless auth like basic and digest authenticate at every request.
Thanks for any advice,
Nicolas
Yes, you can setup multiple strategies:
passport.use(new LocalStrategy(...));
passport.use(new BasicStrategy(...));
and use both of them when authenticating:
app.post('/login', passport.authenticate(['basic', 'local']), ...
just specify an array of strategy names. Authentication attempts them in order, succeeding if any succeed and failing if they all fail.
If you call .isAuthenticated does it also check Basic automatically? One would think it should, or at least I do, lol.
To give some context, I enable Basic on local dev environment to quickly test against multiple API calls, while my production has Auth turned off. But still, shouldn't isAuthenticated check if Basic has been setup, and thus check if the session does not exist via a Local/Facebook/Twitter/etc.
I was struggling with this issue too. In my case, I wanted the api router to support both:
- Session authentication for ajax usage on client-side webpages
- Sessionless basic authentication on programmatic clients
As you've probably experienced already, isAuthenticated
checks only for the existence of the user
property (just grab the source), so it's only useful when the user has already been set by a previous session. If you want to check for a user session (maybe with a pre-existing local
strategy), but fall back to basic
authentication, you can create this middleware:
var ensureAuthenticated = function ensureAuthenticated(req, res, next) {
console.log('ensureAuthenticated');
if (req.isAuthenticated()) {
return next();
}
passport.authenticate('basic', {session: false})(req, res, next);
};
Be aware of the dangers of overloading the authentication strategy - subsequent basic
requests will keep the local
credentials, which can be head-scratching. But it could be helpful during development -- or if you do expect basic
and local
authenticating users to be distinct.