我确信我错过了一些非常明显的东西,但我无法弄清楚这一点。当提交登录表单时,我传递给LocalStrategy构造函数的函数不会被调用。
代码:
var express = require('express');
var http = require('http');
var path = require('path');
var swig = require('swig');
var passport = require('passport');
var LocalStrategy = require('passport-local').Strategy;
passport.serializeUser(function(user, done) {
console.log('Serialize user called.');
done(null, user.name);
});
passport.deserializeUser(function(id, done) {
console.log('Deserialize user called.');
return done(null, {name: 'Oliver'});
});
passport.use(new LocalStrategy(
function(username, password, done) {
console.log('local strategy called with: %s', username);
return done(null, {name: username});
}));
var app = express();
app.set('port', process.env.PORT || 3000);
app.set('view engine', 'swig');
app.set('views', __dirname + '/views');
app.use(express.favicon());
app.use(express.logger('dev'));
app.use(express.bodyParser());
app.use(express.methodOverride());
app.use(express.cookieParser('asljASDR2084^^!'));
app.use(express.session());
app.use(passport.initialize());
app.use(passport.session());
app.use(app.router);
app.use(require('less-middleware')({ src: __dirname + '/public' }));
app.use(express.static(path.join(__dirname, 'public')));
app.use(express.errorHandler({ dumpExceptions:true, showStack:true }));
app.engine('swig', swig.renderFile);
app.post('/auth', passport.authenticate('local'));
app.get('/login', function(req, res) {
// login is a simple form that posts username and password /auth
res.render('login', {});
});
http.createServer(app).listen(app.get('port'), function(){
console.log('Express server listening on port ' + app.get('port'));
});
我的/登录页面上的表单是从护照文档剪切并粘贴的,除了我将其更改为/ auth而不是/ login:
<form action="/auth" method="post">
<div>
<label>Username:</label>
<input type="text" name="username"/>
</div>
<div>
<label>Password:</label>
<input type="password" name="password"/>
</div>
<div>
<input type="submit" value="Log In"/>
</div>
</form>
当我汇总登录表单时,会记录以下内容
GET /login 200 5ms - 432b
POST /auth 401 6ms
请注意,永远不会记录“调用本地策略”。
为什么我传递给LocalStrategy的函数没有被调用?
答案 0 :(得分:72)
我最近遇到过这个问题,可能是由很多事情引起的。首先要检查的是确保bodyParser设置为express,我看到你已经完成了。
app.use(express.bodyParser());
接下来要确保您提交给路线的表单同时包含username
和password
,,并且用户还必须在两个字段中输入内容。我在测试时难以进行一些测试而没有在密码字段中放置任何内容:) Passport要求BOTH执行传递给passport.authenticate('local')
的LocalStrategy验证函数。
您的示例似乎也设置为正确捕获用户名和密码,但无论如何,即使没有护照,您也应该尝试测试正确解析正文:
app.post('/auth', function(req, res){
console.log("body parsing", req.body);
//should be something like: {username: YOURUSERNAME, password: YOURPASSWORD}
});
<强>否则强>
您是否尝试在/auth
路线中添加请求处理程序?
app.post('/auth', passport.authenticate('local'), function(req, res){
console.log("passport user", req.user);
});
或
app.post('/auth', passport.authenticate('local', { successRedirect: '/', failureRedirect: '/auth' }));
答案 1 :(得分:24)
当我设置自己的路由处理程序时,我遇到了同样的问题,我从中调用了passport.authenticate()。我忘记了passport.authenticate返回必须调用的中间件,所以只是调用passport.authenticate是不够的。然后我换了
router.post("/",
function(req,res,next){
passport.authenticate("local", function(err, user, info){
// handle succes or failure
});
})
与
router.post("/",
function(req,res,next){
passport.authenticate("local", function(err, user, info){
// handle succes or failure
})(req,res,next);
})
答案 2 :(得分:16)
当您使用不同的用户名,密码输入字段而不是默认字段时,您将获得401。你必须在你的LocalStrategy中提供这样的:
passport.use(new LocalStrategy({
usernameField: 'login',
passwordField: 'password'
},
function(username, password, done) {
...
}
));
我认为默认为username
和password
。请参阅文档here。
答案 3 :(得分:8)
我认为您提交的表单中包含用户名或密码字段为空。
如果您填写两个输入然后提交,将调用LocalStrategy。
答案 4 :(得分:4)
对于Express 4.x:
// Body parser
var bodyParser = require('body-parser');
app.use(bodyParser.urlencoded({ extended: false })) // parse application/x-www-form-urlencoded
app.use(bodyParser.json()) // parse application/json
答案 5 :(得分:3)
我的问题是,我有enctype ='multipart / form-data'。只需将其更改为multipart ='urlencoded'即可。而且我认为这样可以解决它。
答案 6 :(得分:2)
我也在几个小时内为同样的问题猛烈抨击我。正如其他答案所说的那样我掌握了一切 1.表格正在返回所有领域。 2.正确设置了body解析器,扩展名为:true 3.每个设置和配置的护照。
但是我已经用phoneNumber和密码更改了用户名字段。通过更改下面的代码解决了我的问题
passport.use('login', new LocalStrategy(
{usernameField:'phoneNumber',
passwordField:'password'},
function (username, password, done) {
// your login goes here
})
);
如果有人想要,我可以使用mongodb和本地护照为phonenumber编写整个身份验证程序。
谢谢@ user568109
答案 7 :(得分:0)
您的请求可能没有正确格式化(特别是正文),并且您的用户名和密码在您认为不是时发送。
以下是一个API调用包装器的示例,它强制将您的请求主体解析为json:
Api = {};
Api.request = (route, options) => {
options = options || {};
options.method = options.method || 'GET';
options.credentials = 'include';
if (options.method === 'POST') {
options.headers = {
'Accept': 'application/json',
'Content-Type': 'application/json',
};
options.body = JSON.stringify(options.data) || '{}';
}
fetch(absoluteUrl + '/api/' + route, options)
.then((response) => response.json())
.then(options.cb || (() => {}))
.catch(function(error) {
console.log(error);
});
};
可以这样使用:
Api.request('login', {
data: {
username: this.state.username,
password: this.state.password
},
method: 'POST',
cb: proxy((user) => {
console.log(user);
}, this)
});
答案 8 :(得分:0)
对我来说,一切都设置正确..问题是我收集表单数据,然后从表单数据创建一个json,并将其像JSON.stringify(formdatajson)一样发送到服务器。 (对我而言,登录表单是屏幕上的弹出窗口)
我通过调试passportjs找到了我的错误......
如果您也遇到同样的问题,并且以上解决方案似乎都不适用于您,请调试passportjs。
打开
strategy.js
将调试器放在下面的方法中。
Strategy.prototype.authenticate
检查数据的格式。 希望这有帮助...
答案 9 :(得分:0)
npm install passport-local
var passport = require('passport') ,LocalStrategy = require('passport-local')。策略;
根据passportjs.org,它对我有用!
答案 10 :(得分:0)
还有另一种可能性:对我来说,我在我的body-parser中间件之前意外地定义了路由,因此body-parser从未对登录路由处于活动状态。
答案 11 :(得分:0)
要同时捕获username
和passport
,请确保添加:
app.use(express.urlencoded());
就我而言,我使用的是app.use(express.json());
,并发布了<form>
中的用户名和密码。
答案 12 :(得分:0)
希望总是有人-就我而言,这是我尝试在cookieParser和express-session之前使用护照中间件的事实 这是我的代码:
console.log(result.rows[0].timeid instanceof TimeUuid);
将passportConfig更改为关闭并且可以正常工作:
passportConfig(app);
app.use(cookieParser());
app.use(session({ secret: 'bla' }));
答案 13 :(得分:0)
对我来说,这是行不通的,因为我在登录表单中设置的 name 名称与在password.js中的名称不同,当我在user.name
中更改了{将serializeUser更改为user.username
。
passport.serializeUser(function (user, done) {
done(null, user.username)
})
passport.deserializeUser(function (username, done) {
Users.findOne({
username: username
}).then((user) => {
if (!user) {
return done(new Error("No such user"))
}
return done(null, user)
}).catch((err) => {
done(err)
})
})
答案 14 :(得分:0)
如果您在表单或输入类型中包含 name 属性并且它对应于传递给 localStrategy 回调函数的参数,请检查您的视图中的表单。