Pouya Jabbarisani
Pouya Jabbarisani

Reputation: 1121

check if user logged in by passport Strategy (different user types)

I have two user collections in my db and I want to make different login types for every one, so I have made two strategy on passport for my site ('local-user' & 'local-manager'). My question is how to check logged in user type (by used strategy) in my app?

In this code, passport just checks user auth but I want to check by strategy. (eg: if user logged in by 'local-manager', then show the page)

function isLoggedIn(req, res, next){
    if (req.isAuthenticated()) {
        next();
        return;
    }
    res.redirect('/login');    
}

Upvotes: 1

Views: 2978

Answers (3)

fox1995
fox1995

Reputation: 1

I know this question is old, but I just had the same problem, and I managed to find a way to at least know what kind of account the user is. As someone else said, I don't think there is a way to see what strategy a user used to log in, but if you have a field in your user database to show what kind of account they are (e.g.: admin, client, etc.), then you can pass this information along in the req.user variable when you serialize the user:

passport.serializeUser(function(user, cb) {
  process.nextTick(function() {
    return cb(null, {
      id: user.user_id,
      username: user.user_email,
      type: user.user_type
    });
  });
});

passport.deserializeUser(function(user, cb) {
  process.nextTick(function() {
    return cb(null, user);
  });
});

In the example above, I'm using an SQL database, and one of the columns is called user_type. Once the user is deserialized, passport passes on the fields you ask for in passport.serialize() to req.user. So, if you wanted to know what type of account is currently logged in, you could say something like:

console.log("This user is a(n) " + req.user.type);

Or, something more realistic, if you're using Express:

app.get("/adminsOnly", (req, res) {
  if (req.isAuthenticated() { // returns true if a user successfully logged in
    if (req.user.type === "admin") { //check if user is an admin
      res.render("adminsOnly.ejs"); //render admin section of website if true
    } else {
      res.redirect("/adminsLogin"); //redirected somewhere else because user is not an admin
    }
  } else {
    res.redirect("/login"); //req.isAuthenticated() returns false, so user is redirected to the login page
  }
});
    

I'm pretty new to coding in general, so I'm sure there are better ways to tackle this question, but this is a way to work around the problem of not being able to pinpoint which strategy the user logged in with.

Upvotes: 0

James Drew
James Drew

Reputation: 658

It must be said (and has been in other answers/comments) that you should really look again at your modelling of the domain. User objects can be really simple (just login information) and the rest can be broken out into other models/schemas.

Anyway on to the answer to your original question:

You can switch on the user type. Passport doesn't reach too far into the rest of your application. The log in strategies are not known about outside of the actual log in section.

You can handle that as middleware and add some extra information to the request object by checking for a unique property in one of the models:

function(request, response, next){
    request.isManager = !!(request.user && request.user['unique_prop']);
    next();
}

Place this after the auth middleware. Then in your route you can switch based on request.isManager. Also encapsulating this in middleware will abstract it from the user model and allow you to refactor it in the background.

Another alternative would be to add the function as a static/method/virtual (depending on the implementation) to the schema if you're using mongoose.

Hope this helps 👍 If you have further questions feel free to add comments and I can amend the answer. 🤔

Upvotes: 0

Ebrahim Pasbani
Ebrahim Pasbani

Reputation: 9406

It's better you use role mapping for this.

Anyway for now you can use this concept :

var passport = require('passport')
  , LocalStrategy = require('passport-local').Strategy;

passport.use(new LocalStrategy(
  {passReqToCallback: true},
  function(req, username, password, done) {
     req.usedStrategy = 'local-user';
     //do auth stuff
    });
  }
));

And use like this :

function isLoggedIn(req, res, next){
    if (req.isAuthenticated() && req.usedStrategy === 'local-user') {
        next();
        return;
    }
    res.redirect('/login');

}

Also you can use session if you enable it in passport.

Upvotes: 4

Related Questions