有没有一种方法可以定义使用 passport.authenticate 时要使用的集合

Is there a way of defining what collection to use when using passport.authenticate

在我的项目中,我同时拥有 hcpuser 和普通用户。我已经为 HCP 注册了工作,但是当我执行登录功能时,它仍然只从我的用户集合中读取,而不是从我想要的 hcpuser 中读取。是否有一行简单的代码我可以在我的函数之前声明允许这样做。

Hcp 型号:

var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var bcrypt = require('bcryptjs');
var User = require('../model/user.model').schema

var schema = new Schema({
    email : {type:String, require:true},
    username: {type:String, require:true},
    password:{type:String, require:true},
    creation_dt:{type:Date, require:true},
    hcp : {type:Boolean, require : true},
    clinic:{type:String, require:true},
    patients: [User],
});

schema.statics.hashPassword = function hashPassword(password){
    return bcrypt.hashSync(password,10);
}

schema.methods.isValid = function(hashedpassword){
    return  bcrypt.compareSync(hashedpassword, this.password);
}
schema.set('collection', 'hcpuser');
module.exports = mongoose.model('Hcpuser',schema);

具有第一个寄存器功能的 Hcp 控制器按预期工作。

const express = require("express");
const mongoose = require("mongoose");
const cors = require("cors");

const router = express.Router();
const Hcpusermodel = mongoose.model("Hcpuser")
const {ObjectId} = require("mongodb");
var Hcpuser = require('../model/hcp.model')
var passport = require('passport');

router.post('/register', function (req, res, next) {
    addToDB(req, res);
  });


  async function addToDB(req, res) {

    var hcpuser = new Hcpuser({
      email: req.body.email,
      hcp : true,
      username: req.body.username,
      password: Hcpuser.hashPassword(req.body.password),
      clinic: req.body.clinic,
      creation_dt: Date.now()

    });

    try {
      doc = await hcpuser.save();
      return res.status(201).json(doc);
    }
    catch (err) {
      return res.status(501).json(err);
    }
  }

  //login
  router.post('/login', function(req,res,next){

    passport.authenticate('local', function(err, hcpuser, info) {
      if (err) { return res.status(501).json(err); }
      if (!hcpuser) { return res.status(501).json(info); }
      req.logIn(hcpuser, function(err) {
        if (err) { return res.status(501).json(err); }
        return res.status(200).json({message:'Login Success'});
      });
    })(req, res, next);
  });

从你的问题来看,你要么想验证一个或另一个,要么同时检查两者 - 我想你是在问如何单独验证(一个或另一个,而不是两者)?

请注意,此特定代码未经测试,但原则仍然有效。

一个或另一个

您需要在护照代码中定义每个策略的名称。

例如:

passport.use('users', new LocalStrategy({
  usernameField: 'user[email]',
  passwordField: 'user[password]',
},(email, password, done) => {
  Users.findOne({ email })
    .then((user) => {
      if(!user || !user.validatePassword(password)) {
        return done(null, false, { errors: { 'email or password' : 'is valid' } });
      }
      return done(null, user);
    }).catch(done);
}));


passport.use('hcpusers', new LocalStrategy({
  usernameField: 'user[email]',
  passwordField: 'user[password]',
},(email, password, done) => {
  HCPUser.findOne({ email })
    .then((user) => {
      if(!user || !user.validatePassword(password)) {
        return done(null, false, { errors: { 'email or password' : 'is valid' } });
      }
      return done(null, user);
    }).catch(done);
}));

然后在您的 passport.authenticate 方法中,指定策略名称:

passport.authenticate('users', function(err, user, info) { ...

passport.authenticate('hcpusers', function(err, user, info) { ...

在这种情况下,您需要为每个登录方法使用两个单独的端点,或者只需要一个额外的参数来指定要从 if 语句中检查哪一个。

更新

对于您不知道护照代码应该在哪里的评论,这由您决定。但是,我喜欢将护照代码保存在 'auth' 文件夹中,并将以下代码添加到 passport.js 文件中:

const mongose = require('mongoose');
const passport = require('passport');
const LocalStrategy = require('passport-local');

const Users = mongose.model('Users');

passport.use('...', new LocalStrategy({
...
...
}));

将此包含在您的 server/index/app.js 中(无论您是什么)app.use(passport.initialize());

然后您可以在您的用户控制器中正常使用护照代码。

我的 passport.authenticate 代码如下:

return passport.authenticate('local', function(err, passUser, info) {
    if (err) { 
      return next(err); 
    }
    if (!passUser) { 
      return res.status(503).send('error'); 
    }
    const user = passUser;
    user.token = user.generateJWT();
    return res.json({ token: user.token });
  })(req, res, next);

但这对您来说可能有所不同(即您可能没有使用会话?)无论哪种方式,如果通过身份验证,只需将响应发送给客户端以便它可以继续。

您好,为了解决这个问题,我遵循了所提到的内容。我需要使用以下命令在 hcp 模型中定义集合的名称:

module.exports = mongoose.model('Hcpuser', Hcpuser, 'Hcpuser');

然后我创建了一个本地策略,确保我使用正确的模型进行搜索,然后该模型将指向我的数据库中的正确集合。

解决方案:

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

passport.use('hcplocal', new LocalStrategy(
  function(uemail, password, done) {
    Hcpuser.findOne({ "email" : uemail }, function(err, user) { console.log(user)
      if (err) { return done(err); }
      if (!user) {
        console.log(user);
        console.log(err);

        console.log(uemail)
        return done(null, false, { message: 'Incorrect email.' });

      }
      if (!user.isValid(password)) {
        console.log(user);
        return done(null, false, { message: 'Incorrect password.' });
      }
      return done(null, user);
    });
  }
));


router.post('/login',function(req,res,next){
  passport.authenticate('hcplocal', function(err, user, info) {
    if (err) { return res.status(501).json(err); }
    if (!user) { return res.status(501).json(info); }
    req.logIn(user, function(err) {
      if (err) { return res.status(501).json(err); }
      console.log(user);
      return res.status(200).json({message:'Login Success'});

    });
  })(req, res, next);
});