Есть ли способ определить, какую коллекцию использовать при использовании passport.authenticate - PullRequest
0 голосов
/ 16 апреля 2020

В моем проекте есть как hcpuser, так и обычный пользователь. У меня работает регистрация для HCP, но когда я go выполняю функцию входа в систему, она все еще читает только из моей коллекции пользователей, а не из 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 голосов
/ 20 апреля 2020

Привет, чтобы решить эту проблему, я следовал тому, что было упомянуто. Мне нужно было определить имя коллекции в модели hcp, используя это:

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

Затем я создал локальную стратегию, гарантирующую, что я искал, используя правильную модель, которая затем указывала бы на правильную коллекцию в моем DB.

Решение:

      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);
});
0 голосов
/ 16 апреля 2020

Исходя из вашего вопроса, вы либо хотите авторизовать одно ИЛИ другое, либо проверить оба - я думаю, что вы спрашиваете, как выполнить аутентификацию отдельно (один ИЛИ другой, а не оба)?

обратите внимание, этот специфический c код не проверен, но принципы существуют и остаются в силе.

Один ИЛИ Другой

Вам необходимо определить название каждой стратегии в вашем паспортном коде.

Например:

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» и добавить следующий код в паспорт. js file:

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

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

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

Включите его в свой сервер / 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);

Но это может отличаться для вас (т. Е. Вы не используете сеансы?) В любом случае, если аутентифицировано, просто отправьте ответ клиенту, чтобы он мог продолжить.

...