【问题标题】:Node.js Very Basic Local Authentication using Express Sessions使用快速会话的 Node.js 非常基本的本地身份验证
【发布时间】:2015-09-15 16:55:32
【问题描述】:

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

我查看了各种在线指南,其中大部分都依赖于使用 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;

这对我的目的来说效果很好(尽管有一条错误消息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 个页面并且不想在个案基础上做一些复杂的事情。 IE。我希望验证用户的会话 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 basicAuth() 中间件吗?为所有用户使用一个共享密码,或者您可以在文件上手动编辑几个不同的密码?

标签: javascript node.js session authentication basic-authentication


【解决方案1】:

我去描述如何使用 Express、route、session 和 sequelize (PostgreSQL)。

我建议你使用 Express 框架: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) Route 命名为 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);   

};

【讨论】:

  • 关于提议的解决方案的几个问题。 首先,我将所有这些文件放在哪里?目前我的项目中有以下内容:app.jsnode_modules/public/views/bin/package.jsonroutes/。步骤 2/3/4 是否进入 routes/ 文件夹? 第二步在第 (4) 步中,您正在使用 SQL,同时我怎么能使用 JSON 文件/对象(这只是一个测试阶段,所以我还不想开始散列或加密东西)。 第三在我的(已编辑)问题中,您是将another_page_route.js 内容添加为整个文件,还是仅附加到module.exports
  • 首先,我将所有这些文件放在哪里? R:这个架构它是通过快递提供的,除了中间件。创建一个名为 Middleware 的文件夹并将文件放在那里。步骤 2/3/4 是否进入 routes/ 文件夹? R:不,只有第 3 步和最后一个名为 another_page_route.js 的文件。在第 (4) 步中,您使用的是 SQL[...]。 R:是的,续集支持对象 (docs.sequelizejs.com/en/latest/docs/models-usage)。在我的(已编辑)问题中的第三个 [...]:R:它只是文件路径。需要放入/route/。
猜你喜欢
  • 1970-01-01
  • 2011-11-12
  • 1970-01-01
  • 2011-08-22
  • 2020-07-14
  • 1970-01-01
  • 2014-09-15
  • 2021-11-23
  • 2021-04-30
相关资源
最近更新 更多