How to use the Node Passport.js to login against the database

Asked

Viewed 1,429 times

5

How to use Passport.js to control access using the express.js database and middleware.

How to do login logic and how to know that the session is already authorized when the user has already logged in?

  • I spent all afternoon cracking my head with this... if anyone has other ways it would be interesting to hear! I shared what I did but there’s always more ways to do it...

1 answer

6


The Passport integrates well in the middleware of the express and has asynchronous methods for checking user/pass authenticity.

In my use setup Node-mysql and check with username and password (hashed MD5), and divided the part of Passport in 3 parts:

  • configuration
  • authentication at the time of login
  • check via middleware of req.user

Note: As I understand it, Passport needs the express-session since version 4 of expressjs is a module/middleware apart.

as I did:

First I took care of the Passport configuration on all middleware routes. This includes moving the middleware to the route where I have the secure part of the site: app.use('/admin', middleware.

Then I also set up the interaction part with the database (Mysql via Node-mysql). Not including the initialization part of the DB, but together in the code the query that checks the user/pass against the database using the MD5 to generate the password hash.

After this part of the login, which is different from the middleware of the pages already authenticated, I configured the middleware that checks whether req.user is completed. The passport places on this property of request the user, and so we can know that we are in an authorized/authenticated session.

My setup:

index js.

var express = require('express');
var passport = require('passport');
var session = require('express-session');

var app = express();
var sess = {
  secret: 'keyboard cat',
  cookie: {}
}

if (app.get('env') === 'production') {
  app.set('trust proxy', 1) // trust first proxy
  sess.cookie.secure = true // serve secure cookies
}

app.use('/admin',   session(sess));                         // enable sessions
app.use('/admin',   passport.initialize());                 // configuração do passport
app.use('/admin',   passport.session());                    // configuração do passport
app.use('/admin',   require('./routes/services/admin'));    // router para a zona que requer acesso

Routes/services/admin.js

var md5 = require('md5');
var passport = require('passport');
var LocalStrategy = require('passport-local').Strategy;
var express = require('express');
var router = express.Router();

passport.use(new LocalStrategy(function(username, password, done) {
    // verificação de user/pass
    db.query('SELECT * FROM users WHERE username=? AND password=?', [username, md5(password)], function(err, rows){
        if (err) return done(err);
        var user = rows.length && rows[0].id; // podia passar mais info sobre o utilizador aqui
        done(null, user); // tudo ok! chamar a callback do passport
    });
}));

var authenticate = passport.authenticate('local', {
    // aqui pode configurar-se também sucessRedirect
    failureRedirect: '/admin/login',
    failureFlash: true
});

// configuração recomendada
passport.serializeUser(function(user, done) {
  done(null, user);
});
passport.deserializeUser(function(user, done) {
  done(null, user);
});

// middleware para verificar se a sessão está criada
function gateKeeper(req, res, next){
    if (req.user) next();
    else res.redirect('/admin/login');
}

// página de login
router.get('/login', function(req, res) {
    res.render('admin/login');
});

// tratar os dados de autenticação via POST com o middleware "authenticate"
router.post('/login', authenticate, function(req, res) {
    res.redirect('/admin/home');
});

// router para a parte segura, usando o middleware "gatekeeper"
router.get('/:page', gateKeeper, function(req, res) {
    res.send('Welcome to page ' + req.params.page); // resposta simplificada
});

Disclaimer:

I put this answer after learning the hard way how to do it. If there are mistakes, better ways or things missing: say! In the form of a new reply or comment.

"Disclaimer" that say "for information I will explain something to not think badly of me..." :)

More reading (in English):

Browser other questions tagged

You are not signed in. Login or sign up in order to post.