Node.js 使用快速会话的非常基本的本地身份验证
Node.js Very Basic Local Authentication using Express Sessions
背景 - 我一直在使用 Node.js 构建一个基本网站,现在我已经完成了,运行 我需要建立一个非常本地身份验证的基本形式,使内容仅对少数受信任的用户安全(我可能会选择接受他们——我不想要注册功能)。我研究了一系列选项,包括 JSON Web 令牌、Cookie 等,并决定使用会话,因为它们似乎最容易设置。 (这只需要是一个基本的短期安全功能;它不必很好地扩展或成为在线安全的新标准)。
我看过各种在线指南,其中大部分都依赖于使用 MongoDB 数据库。我不想使用它,因为最终我需要使用 PostgreSQL。一个共同的主题是使用 passport
:
看来我可以避免这些,如下例所示:
使用 express-session
和 cookie-parser
与 Express
我一直在尝试 follow/modify 来自 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.
,但我可以稍后再担心)。 我现在想将此方法合并到我的主网站中。但是,主要网站收集实时数据,我不知道 when/where/how 将其合并到我当前的结构中。我要保护的页面具有以下结构(在 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 页并且不想根据具体情况做一些复杂的事情。 IE。我希望验证用户的会话 ID/username,如果被接受,我希望在 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;
我将描述如何使用 Express、路由、会话和 sequelize (PostgreSQL)。
我建议您使用 Express 框架:http://expressjs.com。
PostgreSQL 的 ORM Sequelize,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);
};
背景 - 我一直在使用 Node.js 构建一个基本网站,现在我已经完成了,运行 我需要建立一个非常本地身份验证的基本形式,使内容仅对少数受信任的用户安全(我可能会选择接受他们——我不想要注册功能)。我研究了一系列选项,包括 JSON Web 令牌、Cookie 等,并决定使用会话,因为它们似乎最容易设置。 (这只需要是一个基本的短期安全功能;它不必很好地扩展或成为在线安全的新标准)。
我看过各种在线指南,其中大部分都依赖于使用 MongoDB 数据库。我不想使用它,因为最终我需要使用 PostgreSQL。一个共同的主题是使用 passport
:
看来我可以避免这些,如下例所示:
使用 express-session
和 cookie-parser
与 Express
我一直在尝试 follow/modify 来自 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.
,但我可以稍后再担心)。 我现在想将此方法合并到我的主网站中。但是,主要网站收集实时数据,我不知道 when/where/how 将其合并到我当前的结构中。我要保护的页面具有以下结构(在 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 页并且不想根据具体情况做一些复杂的事情。 IE。我希望验证用户的会话 ID/username,如果被接受,我希望在 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;
我将描述如何使用 Express、路由、会话和 sequelize (PostgreSQL)。
我建议您使用 Express 框架:http://expressjs.com。 PostgreSQL 的 ORM Sequelize,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);
};