javascript - 使用 Express Sessions 的 Node.js 非常基本的本地身份验证

标签 javascript node.js session authentication basic-authentication

背景 - 我一直在使用 Node.js 构建一个基本网站,现在我已经启动并运行了它,我需要建立一种非常基本的本地身份验证形式,以使内容仅对少数受信任的用户(我可能选择接受的用户 - 我不想要注册功能)安全。我研究了一系列选项,包括 JSON Web token 、Cookie 等,并决定使用 session ,因为它们似乎是最简单的设置。 (这只需是基本的短期安全功能;它不必很好地扩展或成为在线安全的新标准)。

我查看了各种在线指南,其中大多数依赖于使用 MongoDB 数据库。我不想使用这个,因为最终我需要使用 PostgreSQL。一个常见的主题是使用passport:

看来我可以避免这些,如下面的示例所示:

在 Express 中使用 express-sessioncookie-parser

我一直在尝试遵循/修改 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;

这对于我的目的来说相当有效(尽管有一条错误消息错误:发送后无法设置 header 。,但我可以稍后再担心)。 我现在想将此方法合并到我的主网站。然而,主网站收集实时数据,我不知道何时/何地/如何将其合并到我当前的结构中。我想要保护的页面具有以下结构(可在 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。我希望验证用户的 session 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;

最佳答案

我将描述如何使用 Express、路由、 session 和续集 (PostgreSQL)。

我建议您使用Express Framework:http://expressjs.com 。 PostgreSQL、MySQL 的 ORM Sequelize: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) Controller 命名为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);   

};

关于javascript - 使用 Express Sessions 的 Node.js 非常基本的本地身份验证,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32568350/

相关文章:

javascript - jQuery 在文本输入点击时不起作用

javascript - css div动态问题

javascript - switch 语句不执行相应的 block

javascript - 无法访问nodejs中的数组值

node.js - 在 Intern 中调用 Chai 插件返回错误

javascript - 使用服务器端 Javascript 编写脚本

javascript - ReferenceError : Intl is not defined in Node. js

php - CodeIgniter 3 - 具有 PHP 空函数的 session 项 getter

java - 为什么 Hibernate 没有将 session 设置为可自动关闭?

mysql - .Net session ,如何获取数据