背景 - 我一直在使用Node.js构建一个基本网站,现在我已经启动并运行了我需要建立一种非常基本的本地身份验证形式,以确保内容安全只有少数可信用户(我可能会选择接受 - 我不想要注册功能)。我已经研究了一系列选项,包括JSON Web Tokens,Cookies等,并且已经决定使用会话,因为它们似乎是最简单的设置。 (这只需要是一个基本的短期安全功能;它不需要很好地扩展或成为在线安全的新标准。)
我查看了各种在线指南,其中大部分依赖于使用MongoDB数据库。我不想使用它,因为最终我需要使用PostgreSQL。一个共同的主题是使用passport
:
似乎我可以避免这些,如下例所示:
使用express-session
和cookie-parser
使用Express
我一直在尝试关注/修改Simple usage of express-session and cookie-parser with Express中的示例,并在我的app.js
中添加以下内容:
var express = require('express');
var path = require('path');
var favicon = require('serve-favicon');
var logger = require('morgan');
var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser');
var expressSession = require('express-session');
var routes = require('./routes/index');
var users = require('./routes/users');
var private_info = require('./routes/private_info');
var app = express();
app.use(cookieParser());
app.use(expressSession({secret:'somesecret'}));
app.use(bodyParser());
// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'ejs');
// uncomment after placing your favicon in /public
//app.use(favicon(path.join(__dirname, 'public', 'favicon.ico')));
app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));
app.get('/', function(req, res){
var html = '<form action="/" method="post">' +
'Your name: <input type="text" name="userName"><br>' +
'<button type="submit">Submit</button>' +
'</form>';
if (req.session.userName) {
html += '<br>Your username from your session is: ' + req.session.userName;
}
res.send(html);
});
app.get('/private_info', function(req, res){
var html = "You are not allowed to see this private info.";
if (req.session.userName === "oliver") {
html = 'See all this private info...<br/>DATA<br/>DATA<br/>User = ' + req.session.userName;
res.render('private_info', { title: 'Private Info' });
}
res.send(html);
});
app.post('/', function(req, res){
req.session.userName = req.body.userName;
res.redirect('/');
});
app.use('/', routes);
app.use('/users', users);
app.use('/private_info', private_info);
// error handlers
... etc ...
module.exports = app;
这对我的目的来说相当不错(尽管有一条错误消息Error: Can't set headers after they are sent.
,但我稍后会担心)。 我现在想将此方法合并到我的主网站 。但是,主网站收集实时数据,我不知道何时/何地/如何将其合并到我当前的结构中。我想要保护的页面具有以下结构(在routes/predictions.js
中找到):
var express = require('express');
var router = express.Router();
var async = require("async");
var papa = require("papaparse");
var request_retry = require('requestretry');
// long series of function declarations and constructing a chain of call backs
function request_longshot_rob(first_data_list, res) {
//Long series of functions producing a data object called data_for_client.
res.render("predictions", {data: data_for_client});
}
router.get('/', function (req, res, next) {
request_longshot_rob(first_data_list, res);
});
module.exports = router;
如何合并此身份验证请求的最佳方式,特别是如果我想要保护5页并且不希望在具体情况下做一些复杂的事情。即我希望验证用户的会话ID /用户名,如果接受,我希望正常执行routes/predictions.js
中的脚本。
非常感谢任何帮助。
修改
典型的routes/
文件,例如routes/private_info
通常可以具有以下结构:
var express = require('express');
var router = express.Router();
router.get('/', function(req, res, next) {
console.log("private info page function");
res.render('private_info', { title: 'Private Info' });
});
module.exports = router;
答案 0 :(得分:0)
我将介绍如何使用Express,route,session和sequelize(PostgreSQL)。
我建议您使用Express Framework:http://expressjs.com。 ORM Sequelize for PostgreSQL,MySQL:http://docs.sequelizejs.com/en/latest/
app.get
方法有三个参数http://expressjs.com/api.html#app.METHOD:
app.METHOD(path, callback [, callback ...]);
可以这样使用:
app.get(
'/path',
middleware(),
function(req, res) {
res.redirect('/');
}
);
按照这个简单的例子(注意中间件):
1)创建一个前端(EJS,Jade等);
2)中间件名为authentication.js:
module.exports = function(req, res, next) {
if(!req.session.user) {
return res.redirect('/');
}
return next();
};
3)路由名为login.js:
module.exports = function(app){
module.exports = function (app){
var login = app.controllers.login;
app.get('/', login.index);
app.post('/login', login.login);
app.get('/logout', login.logout);
};
4)控制器名为login.js:
module.exports = function(app) {
var sequelize = require('./libs/pg_db_connect');
var LoginController = {
index: function(req, res) {
res.render('login/index');
},
login: function(req, res) {
var query = "SELECT * FROM foo"; // sql for user authentication
sequelize.query(query, { type: sequelize.QueryTypes.SELECT}).then(function(user){
if (!user.length == 0){
if (req.body.login == user[0].login && req.body.senha === user[0].senha ){
req.session.user = primeiroNome[0];
res.redirect("/home");
} else {
res.render("login/invalid_access");
}
} else {
res.render("login/invalid_access");
}
});
},
logout: function(req, res) {
req.session.destroy();
res.redirect('/');
}
};
return LoginController;
};
在所有其他路线中验证用户是否已登录:
文件 another_page_route.js :
module.exports = function(app){
var authentication = require('./middlewares/autenticador')
, another_page = app.controllers.another_page;
app.get('/home/action', authentication, another_page.action);
};