我尝试使用Passportjs和Express设置本地身份验证策略。我有以下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,
};
以下入口点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');
});
我尝试使用以下cURL命令登录,但收到Unauthorized
响应。 curl命令如下:
$ 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
有关如何修改此代码的任何建议都会有所帮助。我一直试图按照stackoverflow post所述的建议,但收效甚微。
答案 0 :(得分:0)
忘记在findOne
的{{1}}顶部注释掉此代码段:
User.js
一旦该块被注释掉,它就会按预期工作。