Theory of Node.js - Node.js, Express.js, Passport.js

I struggle with some theories and conventions behind some Node.js frames. I am new to Node.js. I am trying to set up a scenario where I have an MVC structure, where I define a set of controllers that perform basic rest functions, and some of my controller routes require authentication. If you are not authenticated, it should send you to the login page, but after entering the system, it will send you back to the page that you previously requested. I looked at a bunch of tutorials and I looked at some questions about StackOverflow, but I think the problem is that something just doesn't click. I hope that one of you can explain to me some theory about what is happening and maybe point me in the right direction for my problem. My code is below. My real problem is that I do not understand this next () paradigm. Perhaps I am even doing it all wrong and thinking it wrong. Maybe you can give me some good ideas too.

Edit:

======

I have found a solution. I will answer my question later for anyone who can search for information and solve this problem.

- Server.js

/** * Clancy server implementation (using Express) */ require('console-trace')({ always: true, right: true, colors: true }) /** * Include our server 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

 /** * 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 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(); 

- input controller

 /** * 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 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 middleware

 /** * 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 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(); 

Thanks guys in advance. I love the StackOverflow community. You guys are always so cool when you learn new technology.

+8
source share
1 answer

The return next usually used for Connect middleware. You pass the link to the next function to execute. An intermediate level tool acts like filters or layers in a list (like via a link) that your function calls and executes before it gets to your resources, makes logic, and then decides to exit / redirect or move on to the next middleware. Middleware can be authentication, for example, you use. Despite the fact that Passport is a discrete and well-written module, you implement it as middleware (this is normal), which is basically an authentication filter through your ensureAuthenticated function: you just created your own middleware right there (Achievement is unlocked). You usually put all your middleware right before performing routing functions.

What you define as -- DB Middleware is not middleware, from what I can say. It looks more like a module that you encounter with individual problems (which is good). I would call this the start of your model module.

It looks like your controllers can quickly get out of hand. I suggest exploring Routes .

I am not an expert in any way regarding Node.js, Express.js and Passport.js, but I successfully share the problems and coding organized in a partially working project: https://github.com/Tzvayim/theArk/blob/master /app.js

+1
source share

All Articles