I'm trying to set up the local authentication strategy with sessions using Passportjs and Express. I have the following User.js
var redis = require('redis');
var bcrypt = require('bcrypt-nodejs');
var r = redis.createClient(6379, 'localhost', {no_ready_check: true});
var findOne = function(username, callback){
user = new UserSchema(username);
callback(user.err, user);
get_fields = [
"user:" + username + ":password_hash",
];
r.mget(get_fields, function (err, replies) {
if (err){
callback(err, null);
} else if (replies === null || replies[0] == null) {
callback(null, null);
} else {
password_hash = replies[0]
console.log("findOne Called: " + replies[0])
callback(null, new UserSchema(username, password_hash))
}
});
};
var UserSchema = function (username, password_hash) {
this.username = username;
this.password_hash = password_hash;
this.validPassword = function(password) {
if (this.username === "test"){
console.log("Tested password")
console.log(this)
console.log(this.password_hash)
console.log(this.password_hash === "test")
return this.password_hash === "test"
}
if (this.password_hash === undefined || this.password_hash === null){
return false;
}
return bcrypt.compareSync(password, this.password_hash);
};
};
module.exports = {
findOne : findOne,
UserSchema : UserSchema,
};
And the following entry point app.js
var User = require('./User');
var express = require('express');
var bodyParser = require('body-parser');
var redis = require('redis');
var fs = require('fs');
var http = require('http');
var https = require('https');
var bcrypt = require('bcrypt-nodejs');
var passport = require('passport');
var cookieParser = require('cookie-parser');
var session = require('express-session');
var LocalStrategy = require('passport-local').Strategy;
var privateKey = fs.readFileSync('sslcert/server.key', 'utf8');
var certificate = fs.readFileSync('sslcert/server.crt', 'utf8');
var credentials = {key: privateKey, cert: certificate};
var app = express();
var r = redis.createClient(6379, 'localhost', {no_ready_check: true});
app.use(cookieParser());
app.use(bodyParser.urlencoded({
extended: true,
}));
app.use(session({
secret: 'DEADBEEF0FEEBDAED1DEADBEEF',
resave: false,
saveUninitialized: true,
}));
app.use(passport.initialize());
app.use(passport.session());
passport.use(new LocalStrategy(
function(username, password, done) {
User.findOne(username, function (err, user) {
if (err) { return done(err); }
if (!user) {
return done(null, false, { message: 'Incorrect username.' });
}
if (!user.validPassword(password)) {
return done(null, false, { message: 'Incorrect password.' });
}
console.log(user)
return done(null, user);
});
}
));
passport.serializeUser(function(user, done) {
done(null, user.username);
});
passport.deserializeUser(function(username, done) {
console.log("Deserializing User")
User.findOne(username, function(err, user) {
done(err, user);
});
});
app.get('/', function (req, res) {
res.send('Server Alive');
});
var auth = function(req, res, next){
if (!req.isAuthenticated())
res.sendStatus(401);
else
next();
};
app.get('/test', auth, function (req, res) {
r.get("user:test:password_hash", function(err, reply){
if (err) {
throw err;
}
res.send(reply)
});
// res.send('Server Alive');
});
app.post('/login', passport.authenticate('local'));
var httpServer = http.createServer(app);
var httpsServer = https.createServer(credentials, app);
var httpServerListener = httpServer.listen(8080, function() {
var host = httpServerListener.address().address;
var port = httpServerListener.address().port;
console.log('App listening at http://%s:%s', host, port);
}).on('error', function(err) {
console.error('Cannot serve on port without root privileges:');
console.error('sudo node index.js');
});
var httpsServerListener = httpsServer.listen(8443, function() {
var host = httpsServerListener.address().address;
var port = httpsServerListener.address().port;
console.log('Secure app listening at https://%s:%s', host, port);
}).on('error', function(err) {
console.error('Cannot serve on port without root privileges:');
console.error('sudo node index.js');
});
I'm trying to login with the following cURL command, but I get an Unauthorized
response. The curl commands are as follows:
$ curl -X POST -c jarfile -b jarfile --data "username=test&password=test" -v http://localhost:8080/login
* Hostname was NOT found in DNS cache
* Trying 127.0.0.1...
* Connected to localhost (127.0.0.1) port 8080 (#0)
> POST /login HTTP/1.1
> User-Agent: curl/7.37.1
> Host: localhost:8080
> Accept: */*
> Content-Length: 27
> Content-Type: application/x-www-form-urlencoded
>
* upload completely sent off: 27 out of 27 bytes
< HTTP/1.1 401 Unauthorized
< X-Powered-By: Express
* Added cookie connect.sid="s%3A18MNffLkHj5OwjSazA-S1IDDXSdx5JPb.FWzFtqEt97D6DG7zVaocBoEH%2BX%2Fi0nynrb8tslojpIQ" for domain localhost, path /, expire 0
< set-cookie: connect.sid=s%3A18MNffLkHj5OwjSazA-S1IDDXSdx5JPb.FWzFtqEt97D6DG7zVaocBoEH%2BX%2Fi0nynrb8tslojpIQ; Path=/; HttpOnly
< Date: Thu, 17 Mar 2016 18:32:07 GMT
< Connection: keep-alive
< Transfer-Encoding: chunked
<
* Connection #0 to host localhost left intact
Unauthorized
$ curl -X GET -c jarfile -b jarfile -v http://localhost:8080/test
* Hostname was NOT found in DNS cache
* Trying 127.0.0.1...
* Connected to localhost (127.0.0.1) port 8080 (#0)
> GET /test HTTP/1.1
> User-Agent: curl/7.37.1
> Host: localhost:8080
> Accept: */*
> Cookie: connect.sid=s%3A18MNffLkHj5OwjSazA-S1IDDXSdx5JPb.FWzFtqEt97D6DG7zVaocBoEH%2BX%2Fi0nynrb8tslojpIQ
>
< HTTP/1.1 401 Unauthorized
< X-Powered-By: Express
< Content-Type: text/plain; charset=utf-8
< Content-Length: 12
< ETag: W/"c-4G0bpw8TMen5oRPML4h9Pw"
< Date: Thu, 17 Mar 2016 18:32:37 GMT
< Connection: keep-alive
<
* Connection #0 to host localhost left intact
Unauthorized
Any suggestions for how to modify this code would be helpful. I've been trying to follow the suggestions as described by this stackoverflow post, but have had little success.
Forgot to comment out this snippet at the top of findOne
in User.js
:
user = new UserSchema(username);
callback(user.err, user);
Once this block is commented out, it works as expected.