问题
I was thinking of setting up an like the following. There will be a login page that an admin can access and a worker can access. the admin can make it so that the workers could see certain data(the admin can create workers). The main problem right now is hooking this up with passport. I think the user document look something like this
{username: "user1", password : "pass1", role : "admin",
workers :[
{username : "worker1", password : "workerpass1"},
{username : "worker2", password : "workerpass2"}]
}
Passport does something like the following to check for username and password
passport.use(new LocalStrategy(
function(username, password, done) {
User.findOne({ username: username }, function(err, user) {
........................
I'm wondering how I can get access to the worker level because I think that the passport code above will look at the top username field.
I think I want to do something like this: if on login attempt if username an password is not in the top level go to the workers array and test to see if the username and password matches there
maybe if User.findOne
doesn't find the user do User.worker.findOne()
how would I do that?
回答1:
If you are looking for any of the combinations to match the you basically want an $or query condition, with an $elemMatch to get the username
and password
combination from the specific workers
entry:
passport.use(new LocalStrategy(
function(username,password,done) {
User.findOne({
"$or": [
{ "username": username, "password": password },
{
"workers": { "$elemMatch": {
"username": username, "password": password
}}
}
]
},function(err,user) {
// remaining code
});
}
))
So that means "either" of the conditions listed within the array of $or
can match a document, and the $elemMatch
is used to make sure that both "username" and "password" need to match on the array element, if the main "userame" and "password" was not a match outside of the array.
So its "either/or", and the inspection of the array happens "inside" the query method, and not as a property directly off the model object.
Also noting here that since "username" and "password" are possibly "also" within an array object, then other built in validation methods need to be overriden by the query logic here. So the "query" needs to validate the match, and when an object is returned that is when you return a "valid" result.
That's the cost of customisation. Otherwise, just have separate user accounts, all with the same role you want to apply.
来源:https://stackoverflow.com/questions/35121862/passport-match-username-and-password-in-a-sub-document-if-the-parent-document