【问题标题】:Collision with local strategies passport in two seperate files在两个单独的文件中与本地策略护照冲突
【发布时间】:2017-02-07 02:44:57
【问题描述】:

我有两个模型用户和管理员。他们都有自己的路由文件 users.js 和 admins.js 以及自己的本地策略。用户使用电子邮件进行身份验证,而管理员使用用户名。因此,他们都有自己的“passport.use”,但是,当为用户使用 post '/login' 时,它以某种方式调用了管理员的“passport.use”。我不知道为什么。 这是 users.js 代码:-

var express = require('express');
var router = express.Router();
var bodyParser=require('body-parser');
var User=require('../models/user');
var passport=require('passport');
var localStrategy=require('passport-local').Strategy;

router.post('/login', function(req, res, next) {
  passport.authenticate('local', function(err, user, info) {
    if (err) { 
      return next(err);
    }
    if (!user) {   
      return res.send('User not found'); 
    }
    req.logIn(user, function(err) {
      if (err) { return next(err); }
      return res.json(user);
    });
  })(req, res, next);
});

passport.serializeUser(function(user, done) {
  done(null, user.id);
});

//for sessions
passport.deserializeUser(function(id, done) {
  User.getUserById(id, function(err, user) {
    done(err, user);
  });
});

//this doesnt seem to work..doesnt call this one
passport.use(new localStrategy({usernameField:'email', passwordField:'password'},function(email,password,done){
    User.getUserByUsername(email, function(err,user){
      if(err) throw err;
      if(!user){
        return done(null,false,{message: 'User not found'});
      }

      User.comparePassword(password, user.password, function(err, isMatch){
        if(err) return done(err);
        if(isMatch){
          return done(null, user);
        }
        else{
          return done(null,false,{message: 'Password doesnt match our records'});
        }
      });
    });

  }));

这是 admins.js 代码:-

router.post('/login', function(req, res, next) {
  passport.authenticate('local', function(err, admin, info) {
    if (err) { 
      return next(err);
    }
    if (!admin) { 
      return res.send('Admin not found'); 
    }
    req.logIn(admin, function(err) {
      if (err) { return next(err); }
      return res.json(admin);
    });
  })(req, res, next);
});

//for sessions
passport.serializeUser(function(admin, done) {
  done(null, admin.id);
});

//for sessions
passport.deserializeUser(function(id, done) {
  Admin.getAdminById(id, function(err, admin) {
    done(err, admin);
  });
});
  //this gets called even when im calling /users/login
  passport.use(new localStrategy(function(username,password,done){
    Admin.getAdminByUsername(username, function(err,admin){
      if(err) throw err;
      if(!admin){
        return done(null,false,{message: 'Admin not found'});
      }

      Admin.comparePassword(password, admin.password, function(err, isMatch){
        if(err) return done(err);
        if(isMatch){
          return done(null, admin);
        }
        else{
          return done(null,false,{message: 'Password doesnt match our records'});
        }
      });
    });

  }));

请注意,这两个文件位于 routes 文件夹下的同一级别。它们的模型文件再次位于同一级别的模型文件夹中。管理员工作正常,但用户身份验证没有发生。

【问题讨论】:

    标签: javascript node.js passport.js passport-local


    【解决方案1】:

    问题在于passport.use() 将用于描述策略的逻辑名称作为可选的第一个参数。每个策略算法都提供自己的默认名称。当您执行身份验证时,护照框架会根据该名称选择策略。因此,在您的情况下,local 名称(本地策略的默认名称)的最后一次注册是您获取为该名称注册的最后一个算法。

    解决方案是对 users.js 代码进行以下修改:

    var User=require('../models/user');
    var passport=require('passport');
    var localStrategy=require('passport-local').Strategy;
    
    router.post('/login', function(req, res, next) {
      passport.authenticate('local-users', function(err, user, info) {
        if (err) { 
          return next(err);
        }
        if (!user) {   
          return res.send('User not found'); 
        }
        req.logIn(user, function(err) {
          if (err) { return next(err); }
          return res.json(user);
        });
      })(req, res, next);
    });
    
    passport.serializeUser(function(user, done) {
      done(null, user.id);
    });
    
    //for sessions
    passport.deserializeUser(function(id, done) {
      User.getUserById(id, function(err, user) {
        done(err, user);
      });
    });
    
    //this doesnt seem to work..doesnt call this one
    passport.use('local-users', new localStrategy({usernameField:'email', passwordField:'password'},function(email,password,done){
        User.getUserByUsername(email, function(err,user){
          if(err) throw err;
          if(!user){
            return done(null,false,{message: 'User not found'});
          }
    
          User.comparePassword(password, user.password, function(err, isMatch){
            if(err) return done(err);
            if(isMatch){
              return done(null, user);
            }
            else{
              return done(null,false,{message: 'Password doesnt match our records'});
            }
          });
        });
    
      }));
    

    如您所见,我们在用户模块的上下文中为 LocalStrategy 提供了一个替代策略名称。我们正在使用这个特定策略名称的策略(在passport.authenticate 调用上)。

    【讨论】:

    • 非常感谢朋友。在文档中找不到这个东西,或者我错过了它。奇迹般有效。你拯救了我的一天
    猜你喜欢
    • 1970-01-01
    • 2016-05-29
    • 2016-10-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-09-12
    相关资源
    最近更新 更多