使用护照允许两种完全不同类型的"用户"进行身份验证

时间:2017-10-03 04:34:53

标签: node.js express passport.js

所以,我有一个应用程序有两种类型的'用户':人类和设备。

人类使用用户名/密码登录(本地策略)。 设备使用证书登录。

它们是非常不同的东西,因此这与管理员用户与普通用户的特殊访问权限不同。我无法为所有可以登录的实体提供单个数据库表。

我理解如何拥有多个身份验证策略(我只是按端点区分),但我对如何处理传入请求的令牌反序列化感到有点困惑。 Express / passport似乎只允许我可以编写一个deserializeUser函数。

此外,我想将这两种类型解耦,这样我就可以将设备和人类保存在自己的代码中,而不是使用单一的反序列化函数来对它们进行排序。

理想情况下,我可以使用两个deserializeUser函数,并根据令牌格式调用正确的函数,但我不知道如何最好地执行此操作。

有什么建议吗?

2 个答案:

答案 0 :(得分:1)

我最终标准化了每个用户类型必须具有的最小公共元素集:

  • id(使用mongo' s _id)
  • type(定义为mongoose virtual)

这允许我在序列化中包含类型,并且只在反序列化时在正确的表中查找实体。

这与我希望得到的非常接近。我宁愿不必使用中央串行器/解串器功能,但我觉得这是我可以做的最小折衷。

这是序列化和反序列化的代码:

passport.serializeUser(function (entity, done) {
    done(null, { id: entity.id, type: entity.type });
});

passport.deserializeUser(function (obj, done) {
    switch (obj.type) {
        case 'user':
            User.findById(obj.id)
                .then(user => {
                    if (user) {
                        done(null, user);
                    }
                    else {
                        done(new Error('user id not found:' + objid, null));
                    }
                });
            break;
        case 'device':
            Device.findById(obj.id)
                .then(device => {
                    if (device) {
                        done(null, device);
                    } else {
                        done(new Error('device id not found:' + obj.id, null));
                    }
                });
            break;
        default:
            done(new Error('no entity type:', obj.type), null);
            break;
    }
});

答案 1 :(得分:0)

我理解您的要求是您需要不同的用户类型登录,因此您可以使用护照中的请求参数来识别用户类型,以便您的功能保持通用。

    passport.use(new LocalStrategy({
        usernameField: 'email',
        passwordField: 'password',// this is the virtual field on the model
        passReqToCallback: true
    },
    function (req, email, password, done) {  
       // get req here 
       enter code here
    });