在 mongo、node、passport 和 heroku 上对用户进行身份验证。几天后停止工作
Posted
技术标签:
【中文标题】在 mongo、node、passport 和 heroku 上对用户进行身份验证。几天后停止工作【英文标题】:Authenticating users on mongo, node, passport, and heroku. Stops working after a few days 【发布时间】:2013-08-21 23:21:13 【问题描述】:我正在使用 mongo、express、angular 和 node 创建我的第一个全栈 Web 应用程序。我来自前端背景,我在身份验证实现方面有点挣扎。
我的(不完整的)应用程序运行了好几天,但今天它突然坏了,然后我神奇地修复了它。我很确定我没有对代码进行任何重大更改。该错误导致所有经过身份验证的用户都看到“来宾用户”帐户。这将允许他们登录,但用户将以 guestuser 身份从 mongo 返回。你看到我在这段代码中遗漏了什么吗?
var express = require('express'),
routes = require('./routes'),
api = require('./routes/api'),
http = require('http'),
path = require('path'),
mongoose = require('mongoose'),
passport = require('passport'),
LocalStrategy = require('passport-local').Strategy;
var app = module.exports = express();
var uristring =
process.env.MONGOLAB_URI ||
process.env.MONGOHQ_URL ||
'mongodb://localhost/HelloMongoose';
mongoose.connect(uristring, function (err, res)
if (err)
console.log ('ERROR connecting to: ' + uristring + '. ' + err);
else
console.log ('Succeeded connected to: ' + uristring);
);
var Schema = mongoose.Schema,
ObjectId = Schema.ObjectId;
var Tasks = new Schema(
"title": String,
"description": String,
"difficulty": Number,
"completed": Boolean
);
var Project = new Schema(
"title": String,
"tasks": [ Tasks ]
);
var User = new Schema( // update data model here
"first_name": String,
"last_name": String,
"email": type: String, unique: true,
"username": type: String, unique: true,
"password": String,
"projects": [ Project ]
);
var User = mongoose.model('User', User);
User.prototype.validPassword = function(pass)
return (this.password === pass);
/**
* Configuration
*/
// all environments
app.set('port', process.env.PORT || 3000);
app.set('views', __dirname + '/views');
app.set('view engine', 'jade');
app.use(express.logger('dev'));
app.use(express.bodyParser());
app.use(express.methodOverride());
app.use(express.static(path.join(__dirname, 'public')));
app.use(express.cookieParser());
app.use(express.session( secret: 'keyboardcat' ));
app.use(passport.initialize());
app.use(passport.session());
app.use(app.router);
// development only
if (app.get('env') === 'development')
app.use(express.errorHandler());
// production only
if (app.get('env') === 'production')
// TODO
;
passport.use(new LocalStrategy(
function(username, password, done)
mongoose.model('User').findOne( username: username , function (err, user)
if (err)
console.log('There was an error');
return done(err);
if (!user)
console.log('Username invalid');
return done(null, false, message: 'Incorrect username.' );
if (!user.validPassword(password))
console.log('Password incorrect');
return done(null, false, message: 'Incorrect password.' );
return done(null, user);
);
));
passport.serializeUser(function(user, done)
done(null, user.id);
);
passport.deserializeUser(function(id, done)
User.findOne(id, function (err, user)
done(err, user);
);
);
/**
* Routes
*/
// serve index and view partials
app.get('/', routes.index);
app.get('/login', function(req, res)
console.log(req.session.user);
if (!req.session.user)
res.render('login');
else
res.redirect('/');
);
app.post('/login', passport.authenticate('local',
failureRedirect: '/login'
), function(req, res)
req.session.user = req.body.username;
res.redirect('/');
);
app.get('/signup', function(req, res)
if (!req.session.user)
res.render('signup');
else
res.redirect('/');
);
app.get('/logout', function(req, res)
req.session.user = undefined;
res.redirect('/login');
);
app.post('/signup', function(req,res)
if (req.body.username && req.body.password)
var user = new User(
first_name: req.body.first_name,
last_name: req.body.last_name,
email: req.body.email,
username: req.body.username,
password: req.body.password
);
user.save(function(err)
if (!err)
console.log(user.username);
req.session.user = req.body.username;
res.redirect('/');
else
console.log(err);
res.redirect('/signup');
);
else
res.redirect('/signup');
);
app.get('/person', function(req,res)
if (!req.session.user)
res.redirect('/login');
else
mongoose.model('User').findOne(username: new RegExp('^'+req.session.user+'$', "i"), function(err, user)
if (!err)
console.log(JSON.stringify(user));
res.send(user);
else
console.log(err);
);
);
app.put('/person', function(req,res)
if (!req.session.user)
res.redirect('/login');
else
console.log('Updating user');
console.log(req.body.projects);
mongoose.model('User').findOne(username: new RegExp('^'+req.session.user+'$', "i"), function(err, user)
console.log(user);
user.projects = req.body.projects;
console.log(user.first_name + ' is here');
user.save(function(err)
if (!err)
console.log('User updated');
else
console.log(err);
);
);
);
app.get('/:user', function(req, res)
if (!req.session.user)
res.redirect('/login');
else if (req.params.user != req.session.user)
res.redirect('/' + req.session.user);
else
res.render('index');
);
app.get('/partials/:name', routes.partials);
// JSON API
app.get('/api/name', api.name);
// redirect all others to the index (html5 history)
app.get('*', function(req, res)
if (!req.session.user)
res.render('login');
else
res.redirect('/');
);
/**
* Start Server
*/
http.createServer(app).listen(app.get('port'), function ()
console.log('Express server listening on port ' + app.get('port'));
);
【问题讨论】:
您可能希望从 Mongo DB 中获取记录并验证它们是有效的 JSON (JSON Lint)。确保对 URI 组件进行编码、转义 val、验证您的字段。错误数据可能导致服务器响应失败,然后默认返回 我认为 /user 路由也可能是可疑的 - 会话中间件可能出现问题并将它们作为访客发送到 /index 【参考方案1】:假设您的大部分代码来自 here,我可以看到您对其进行了更改,这可能会导致失败。
passport.use(new LocalStrategy(
function(username, password, done)
mongoose.model('User').findOne( username: username , function (err, user)
您已将 validPassword
添加到 User
,所以应该是这样的
passport.use(new LocalStrategy(
function(username, password, done)
User.findOne( username: username , function (err, user)
【讨论】:
【参考方案2】:自:
用户将以 guestuser 身份从 mongo 返回
...您可能应该在此处放置一些日志记录和/或错误处理:
passport.deserializeUser(function(id, done)
User.findOne(id, function (err, user)
done(err, user);
);
);
帮助您追踪它。由于您才刚刚开始,如果您想探索在 node/heroku 中的日志记录工具,我建议您看看 winston 和 loggly。
您的应用程序看起来非常“有弹性”,用一句话来说——大量的重定向似乎无处不在。您是否看过 fnakstad's technique 进行节点/角度身份验证? (请注意,github 页面引用了两篇解释事情的博客文章)。它可能会给你一些关于如何控制事情的想法。
【讨论】:
感谢您的反馈。我会检查并与您联系。以上是关于在 mongo、node、passport 和 heroku 上对用户进行身份验证。几天后停止工作的主要内容,如果未能解决你的问题,请参考以下文章
phonegap ajax 用户身份验证与 nodejs-express-mongodb-passport js
在节点应用程序上使用 mongoose 的远程 mongo 身份验证问题
在节点应用程序上使用 mongoose 的远程 mongo 身份验证问题
仍然需要使用带有 passport.js 的 cookie-parser 吗?