我有两个模型用户和管理员。他们都有自己的路由文件 users.js 和 admins.js 以及自己的本地策略。用户使用电子邮件进行身份验证,而管理员使用用户名。所以他们都有自己的“passport.use”,但是,当用户使用帖子“/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'});
}
});
});
}));
请注意,这两个文件位于路由文件夹下的同一级别......并且它们的模型文件再次位于同一级别的模型文件夹中。管理员工作正常,但用户身份验证没有发生。
最佳答案
问题在于 passport.use()
将用于描述策略的逻辑名称作为可选的第一个参数。每个策略算法都提供自己的默认名称。当您执行身份验证时, Passport 框架会根据该名称选择策略。因此,在您的情况下,您将获取为该名称注册的最后一个算法。
解决方案是对 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
调用中)。
关于javascript - 与两个单独文件中的本地策略 Passport 发生冲突,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39759037/