Reputation: 8376
I got below express
node.js
server code using Passport
. At it my whole routes definition depends upon a MongoDB connection using mongo-db
but model used by Passport is done through another connection by mongoose
. I mention these two details cause I think it should also be coded in a better way.
However, the main problem is that even though Passport it's doing it's work, I still can go to localhost/registro
directly no matter I didn't logged in first.
When someone tried to access to localhost/registro
it should be redirected to start page if a login and authentication wasn't done first.
I care about a safe implementation of it, I'd also like to have some information about the user during the session time.
I'm quite confused about what I should try, cookies, sessions, etc. Apart that in new express version middlewares work different than before.
This is my server.js
:
var express = require('express')
var mongodb = require('mongodb')
var mongoose = require('mongoose')
var bodyParser = require('body-parser')
var passport = require('passport')
var LocalStrategy = require('passport-local').Strategy;
var app = express()
var BSON = mongodb.BSONPure
app.use(passport.initialize());
app.use(passport.session());
app.use(express.static(__dirname+"/public"))
app.use(bodyParser())
var MongoDBClient = mongodb.MongoClient
mongoose.connect('mongodb://localhost/psicologosTuxtepecDB')
var Schema = mongoose.Schema
var userCredential = new Schema({
username: String,
password: String
}, {
collection: 'members'
})
var userCredentials = mongoose.model('members', userCredential)
passport.serializeUser(function(user, done) {
done(null, user);
})
passport.deserializeUser(function(user, done) {
done(null, user);
})
passport.use(new LocalStrategy(function(username, password, done) {
process.nextTick(function() {
userCredentials.findOne({
'username': username,
}, function(err, user) {
if (err) {
return done(err);
}
if (!user) {
return done(null, false);
}
if (user.password != password) {
return done(null, false);
}
return done(null, user);
});
});
}));
MongoDBClient.connect("mongodb://localhost/psicologosTuxtepecDB", function (error, psicologosTuxtepecDB) {
if (error) {
console.log("We've got a connection error, so far we should take this function better for a correct debug")
}
else {
console.log("Connection to psicologosTuxtepecDB has been successful")
// Seleccionamos una colección
var psicologosCollection = psicologosTuxtepecDB.collection("psicologos")
app.get('/registro', function(request,response) {
response.sendfile("public/html/registro.html")
})
// Cuando nos hagan una petición HTTP de tipo POST en la ruta psicologos...
app.post("/psychos", function(request, response) {
var psychologist = {
personalData: request.body._personalData,
professionalData: request.body._professionalData,
professionalInterests: request.body._professionalInterests
}
psicologosCollection.insert(psychologist, function(error, responseFromDB) {
if (error) {response.send(responseFromDB)}
console.log("Se ha insertado: "+ JSON.strinfigy(responseFromDB))
response.send(responseFromDB)
})
})
app.get("/psychos/:id", function(request, response) {
var id = new BSON.ObjectID(peticion.params.id)
psicologosCollection.findOne(
{'_id':id},
function(error,responseFromDB) { if (error) {response.send(responseFromDB)} response.send(responseFromDB)}
)
})
app.get("/psychos", function(request,response) {
psicologosCollection.find().toArray(function(error,responseFromDB) {
if (error) {response.send(responseFromDB)}
response.send(responseFromDB)
})
})
app.post('/login',
passport.authenticate('local', {
successRedirect: '/loginSuccess',
failureRedirect: '/loginFailure'
})
)
app.get('/loginFailure', function(req, res, next) {
res.redirect('/')
})
app.get('registro', function(request, response) {
response.sendfile('public/html/registro.html')
})
app.get('/loginSuccess', function(req, res, next) {
res.redirect('/registro')
})
app.listen(80, function () {
console.log("app escuchando en el puerto Maricela fecha de nacimiento DDMM")
})
}
})
These are my Passport statements:
app.use(passport.initialize());
app.use(passport.session());
passport.serializeUser(function(user, done) {
done(null, user);
})
passport.deserializeUser(function(user, done) {
done(null, user);
})
passport.use(new LocalStrategy(function(username, password, done) {
process.nextTick(function() {
userCredentials.findOne({
'username': username,
}, function(err, user) {
if (err) {
return done(err);
}
if (!user) {
return done(null, false);
}
if (user.password != password) {
return done(null, false);
}
return done(null, user);
});
});
}));
Upvotes: 0
Views: 2626
Reputation: 4373
Express "chains" route methods. The basic idea behind securing routes in Express.js is to have a method that checks the a&a before allowing the request to proceed to the intended route. There are a few ways to do this:
Method 1: Add the auth method to the route declaration
function requireAuth(req,res,next){
if user is authenticated
next();
else
res.send(401);
}
app.get('/registro', requireAuth, function(request, response) {
response.sendfile('public/html/registro.html')
})
Method 2: Declare a route handler for your auth
app.get('/registro', function(req,res,next){
if user is authenticated
next();
else
res.send(401);
})
app.get('/registro', function(request, response) {
response.sendfile('public/html/registro.html')
})
Method 3: Use app.use() instead of a verb
With this method, you need to consider when app.router gets inserted into the middle-ware.
Edit 1: Where would the require auth method be declared If you plan on placing route handlers in multiple .js files, it's a good idea to put your require auth mehtod in a separate .js file as well and require it where appropriate.
Otherwise, you can just stick it in the same file with everything else.
Edit 2: How do sessions work in Express.js and Passport.js
From the Passport.js documentation, you first need to configure the express session before the passport session:
app.use(express.session({ secret: 'keyboard cat' }));
app.use(passport.initialize());
app.use(passport.session());
Note: You should probably consider using something other than the memory store for session management.
Along with the serializeUser and deserializeUser methods, at this point Passport will have placed a .user on the request.
You can also use req.isAuthenticated()
to determine if the user is authenticated.
Note 2: I've had problems getting the serializeUser and deserializeUser methods to work with Passport-Saml. If that is the case, just manage the session yourself.
Upvotes: 2