我正在为一些Node.js框架背后的一些理论和惯例而奋斗。我是Node.js的新手。我正在尝试建立一个场景,其中我有一个MVC框架,其中我定义了一组控制器,这些控制器具有基本的rest功能,而我的某些Controller路由需要身份验证。如果您没有经过身份验证,它应该会将您发送到login页面,但是在您登录后,它会将您发送回您先前请求的页面。我看过一堆教程,也看过一些关于StackOverflow的问题,但我认为问题是,有些东西只是没有点击。我希望你们中的一个能向我解释一下发生了什么事情背后的一些理论,也许能为我的问题指明正确的方向。我的密码在下面。我真正的问题是,我并不真正理解下一个()范例。也许我甚至做错了这一切,并以错误的方式思考它。也许你也能让我知道一些好主意。
编辑:
======
我找到了解决办法。我稍后会回答我的问题,为其他人谁可能希望获得一些信息,并解决这个问题,也。
-- Server.js
/**
* Clancy server implementation (using Express)
*/
require('console-trace')({
always: true,
right: true,
colors: true
})
/**
* Include our server's needed objects.
**/
var express = require('express');
var _ = require('underscore');
var cons = require('consolidate');
passport = require('passport'),
LocalStrategy = require('passport-local').Strategy;
var db = require('./lib/db');
var colors = require('colors');
var Users = db.users;
var People = require('./controllers/People');
var Login = require('./controllers/Login');
/**
* This provides our MVC context object
**/
var app = express();
/**
* This is our router definition for the server
**/
app.engine('html', cons.underscore);
// set .html as the default extension
app.set('view engine', 'html');
app.set('views', __dirname + '/views');
/**
* Set up the server to allow static content, cookies, session, and
* parsing the server. Also, we initialize authentication and our
* routing mechanism.
*
*/
app.configure(function () {
app.use('/static', express.static(__dirname + "/webapp"));
app.use(express.cookieParser());
app.use(express.bodyParser());
app.use(express.session({
secret: 'keyboard cat'
}));
app.use(passport.initialize());
app.use(passport.session());
app.use(app.router);
});
/**
* This lets authentication know how it should store
* and grab users from a request to pass to a mapping
* function.
*/
passport.serializeUser(function (user, done) {
done(null, user._id);
});
passport.deserializeUser(function (id, done) {
Users.findOne({
_id: db.bson.ObjectID(id)
}, function (err, user) {
done(err, user);
});
});
/**
* This sets up which authentication strategies we support.
* as of right now, LocalStrategy (our own username/password)
* is all we support.
*
*/
passport.use(new LocalStrategy(
function (username, password, done) {
Users.findOne({
username: username
}, function (err, user) {
if (err) {
return done(err);
}
if (!user) {
return done(null, false, {
message: 'Incorrect username.'
});
}
if (!(user.password == password)) {
return done(null, false, {
message: 'Incorrect password.'
});
}
console.info(user.password + " " + password.yellow);
console.info(!(user.password == password).yellow);
console.info(user._id);
return done(null, user);
});
}));
/**
* Path mapping
*/
// Index mapping
app.get('/', function (req, resp) {
resp.render('index', {
title: "Welcome!"
});
});
// Allow login, and set up the dependency for passport.
Login.setPassport(passport);
app.get("/login", Login.loginForm);
app.get("/login/error", Login.loginForm);
app.post('/login', passport.authenticate('local', function (req, res, next) {
passport.authenticate('local', function (err, user, info) {
// This is the default destination upon successful login.
var redirectUrl = '/people';
if (err) {
return next(err);
}
if (!user) {
return res.redirect('/');
}
// If we have previously stored a redirectUrl, use that,
// otherwise, use the default.
if (req.session.redirectUrl) {
redirectUrl = req.session.redirectUrl;
req.session.redirectUrl = null;
}
req.logIn(user, function (err) {
if (err) {
return next(err);
}
});
res.redirect(redirectUrl);
})(req, res, next);
}));
app.get('/logout', Login.logout);
// People Controller has a dependency on the Passport library
People.setPassport(passport);
// These are our definitions for paths the People Controller can handle.
app.get("/people", People.list);
app.get("/people/:id", People.get);
// These are the error handler mappings.
app.use(function (req, res, next) {
// the status option, or res.statusCode = 404
// are equivalent, however with the option we
// get the "status" local available as well
res.render('404', {
status: 404,
url: req.url
});
});
app.use(function (err, req, res, next) {
// we may use properties of the error object
// here and next(err) appropriately, or if
// we possibly recovered from the error, simply next().
console.error(("ERROR: " + err.toString()).red);
res.render('500', {
status: err.status || 500,
error: err
});
});
app.listen(3000);
console.info('The Clancy server is listening on port: 3000'.green);-人民控制器
/**
* People Controller
*/
var db = require('../lib/db');
var auth = require('../lib/authUtils');
/**
* People constructor.
* ===================
* The people constructor has dependencies on the database,
* and on the Passport middleware. The db object doesn't
* care about maintaining state, so we can just include that
* here, however the Passport plugin needs to have all of the
* stuff the server defines. So, it's passed in.
*/
function People(){
var passport;
}
People.prototype = {
list: function(req, resp){
auth.ensureAuth(req, resp);
console.info("user info: " + user._id);
resp.render('index', {
title: "User",
users: [1,2,3]
});
},
get: function(req, resp){
console.log('> get person' + req.params.id);
db.users.find( {_id: db.bson.ObjectID(id)}, function(err, users){
if(err || !users) console.log("No user found");
resp.send(users);
});
},
setPassport: function(pass){
this.passport = pass;
},
getPassport: function(){
return this.passport;
}
}
module.exports = new People();-登录主计长
/**
* People Controller
*/
/**
* Login constructor.
* ===================
* The Login constructor has dependencies on the Passport middleware.
* The db object doesn't care about maintaining state, so we can just
* include that here, however the Passport plugin needs to have all
* of the stuff the server defines. So, it's passed in.
*/
function Login(){
var passport;
}
var l = Login.prototype;
Login.prototype = {
loginForm: function(req, resp){
var url = require('url').parse(req.url, true);
console.info('url string: ' + url.pathname.yellow);
if(url.pathname === '/login/error')
{
resp.render('login', {
title: "Login to FormPickle.com",
message: "Your username or password was incorrect."
});
}
console.info('Trying to login'.yellow);
resp.render('login', {
title: "Login to FormPickle.com",
message: ""
});
},
setPassport: function(pass){
l.passport = pass;
},
getPassport: function(){
return l.passport;
},
logout: function(req, resp){
req.logout();
resp.render('logout');
}
}
module.exports = new Login();- DB中间件
/**
* DB
*/
var databaseURI = "localhost:27017/clancy";
var collections = ["users", "forms"];
var db = require("mongojs").connect(databaseURI, collections);
module.exports = db;-- AuthUtils.js
/***
* Define a middleware function for authenticated routes to store the original URL
*
*/
function Auth(){
};
Auth.prototype = {
ensureAuth: ensureAuthenticated(req, resp, next)
}
var ensureAuthenticated = function (req, res, next) {
if (req.isAuthenticated()) { return next(); }
// If the user is not authenticated, then we will start the authentication
// process. Before we do, let's store this originally requested URL in the
// session so we know where to return the user later.
req.session.redirectUrl = req.url;
// Resume normal authentication...
logger.info('User is not authenticated.');
req.flash("warn", "You must be logged-in to do that.");
res.redirect('/login');
}
module.exports = new Auth();提前谢谢你们。我喜欢StackOverflow上的社区。你们学习新技术的时候总是那么棒。
发布于 2013-07-31 23:47:12
返回next通常用于Connect中间件。您正在传递要执行的下一个函数的引用。中间件的作用就像筛选器,或者链接列表层(某种程度上,通过引用),函数在访问资源之前调用这些层,然后执行逻辑操作,然后决定退出/重定向或转到下一个中间件。中间件可能是身份验证,如您所使用的。尽管Passport是一个离散且编写良好的模块,但您在这里将它实现为中间件(这是正常的),这基本上是通过您的ensureAuthenticated函数进行身份验证的过滤器:您基本上只是在那里创建了自己的中间件(成绩未锁定)。通常将所有中间件放在执行路由函数之前。
据我所知,您定义的-- DB Middleware不是中间件。它看起来更像一个模块,您正在尝试单独关注这个模块(这很好)。我认为这是model模块的开始。
看起来你的控制器可能很快就失控了。我建议研究Routes。
我并不是Node.js、Express.js和Passport.js方面的专家,但我成功地将关注点和编码组织在一个部分工作的项目中:https://github.com/Tzvayim/theArk/blob/master/app.js
https://stackoverflow.com/questions/13938067
复制相似问题