passport match username and password in a sub document if the “parent” document doesn't have any matching username and passwords

巧了我就是萌 提交于 2019-12-25 04:33:32

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!