有没有一种方法可以定义在使用passport.authenticate

时间:2020-04-16 13:29:28

标签: node.js mongodb express mongoose passport.js

在我的项目中,我既有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);
  });

2 个答案:

答案 0 :(得分:0)

从您的问题开始,您要么想对一个进行身份验证,要么对两者进行验证-我想您是在询问如何分别进行身份验证(一个或另一个,而不是两者)?

请注意,此特定代码未经测试,但原理仍然存在。

一个或另一个

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

例如:

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”文件夹中,并将以下代码添加到password.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);

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

答案 1 :(得分:0)

嗨,为了解决这个问题,我遵循了所提到的内容。我需要使用以下方法在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);
});