我目前正在学习节点,postgres和护照,但我不确定如何保护我的应用程序和最佳实践。我不确定如何清理来自客户端和服务器的数据,或者是否需要,但我已经参数化了我的查询。任何帮助将不胜感激!为我的新手道歉。
var express = require('express');
var helmet = require('helmet')
var bodyParser = require('body-parser');
var cookieParser = require('cookie-parser');
var expressSession = require('express-session');
var passport = require('passport');
var passportLocal = require('passport-local');
var pg = require ('pg');
var bcrypt = require('bcryptjs');
var app = express();
app.use(helmet());
var server = require('http').createServer(app);
var io = require('socket.io')(server);
var config = {
user: 'REDACTED',
database: 'REDACTED',
password: 'REDACTED',
host: 'REDACTED',
port: 5432,
max: 10,
idleTimeoutMillis: 30000,
};
var pool = new pg.Pool(config);
pool.on('error', function (err, client) {
console.error('idle client error', err.message, err.stack)
})
app.use(bodyParser.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(expressSession( {
secret: process.env.SESSION_SECRET || 'secret',
resave: false,
saveUninitialized: false
}));
app.use(passport.initialize());
app.use(passport.session());
passport.use(new passportLocal.Strategy(function(username, password, done) {
pool.connect(function(poolErr, poolClient, poolDone) {
if(poolErr) {
return console.error('pool client fetch error', poolErr);
}
poolClient.query('SELECT id, password FROM users WHERE username = $1', [username], function(queryErr, queryRes) {
if(queryErr) {
return console.error('query error', queryErr);
}
if(queryRes.rows[0] != undefined)
{
bcrypt.compare(password, queryRes.rows[0].password, function(compareErr, compareRes) {
if(compareErr) {
return console.error('bcrypt error', compareErr);
}
if(compareRes) {
done(null, { id: queryRes.rows[0].id });
} else {
done(null, null);
}
poolDone();
});
} else {
//user not found
poolDone();
done(null, null);
}
});
});
}));
passport.serializeUser(function(user, done) {
done(null, user.id);
});
passport.deserializeUser(function(id, done) {
pool.connect(function(err, poolClient, poolDone) {
if(err) {
return console.error('pool client fetch error', err);
}
poolClient.query('SELECT * FROM users WHERE id = $1', [id], function(queryErr, queryRes) {
if(queryErr) {
return console.error('query error', queryErr);
}
if(queryRes.rows[0] != undefined)
{
done(null, { id: id, username: queryRes.rows[0].username, firstname: queryRes.rows[0].firstname, lastname: queryRes.rows[0].lastname });
} else {
//user not found
done(null, null);
}
poolDone();
});
});
});
app.set('view engine', 'ejs');
app.get('/', function(req, res) {
res.render('index', {
isAuthenticated: req.isAuthenticated(),
user: req.user
})
});
app.get('/login', function(req, res) {
res.render('login');
});
app.post('/login', passport.authenticate('local'), function(req, res) {
res.redirect('/');
});
app.get('/logout', function(req, res) {
req.logout();
res.redirect('/');
});
server.listen(8080);
console.log('Server is running...');

答案 0 :(得分:1)
我没有看到太多问题,但这是我的2分来改进它。
使用压缩来缩小网络规模
app.use(require('compression'));
将serve-static用于静态文件,如图像或pdf
app.use(require('serve-static')('./public'))
使用中间件来控制需要身份验证的终端,例如查看/编辑个人资料,更改密码等
function authenticated(req, res, next) {
if (req.isAuthenticated()) next();
else {
res.status(401).send('User not authenticated.');
// or redirect to login
}
}
app.get('/profile', authenticated, function(req, res) {
res.render('profile', {
req.user
})
})
注销时包含会话销毁
app.get('/logout', function(req, res) {
req.session.destroy();
req.logout();
res.redirect('/');
});
答案 1 :(得分:1)
用于清理查询,您可以使用ORM,如sequelise