【问题标题】:Node.js - How do I set up separate authentication for different routes?Node.js - 如何为不同的路由设置单独的身份验证?
【发布时间】:2017-11-07 12:07:03
【问题描述】:

我正在开发 Node.js 项目,该项目使用 basic-auth 进行密码保护。目前,auth.js 文件为所有路由提供相同的用户名/密码。我将如何调整它以为每条路线使用不同的用户名/密码?

auth.js 文件:

const auth = require('basic-auth');
const username = 'admin';
const password = 'supersecret';
const internalIp = 'xxx.xx.xxx.xxx';

module.exports = function(app) {

  app.use((req, res, next) => {
    const ip = req.headers['x-forwarded-for'] || req.connection.remoteAddress;

    // whitelist internal IP
    if (ip === internalIp) {
      next();
    } else {

      const user = auth(req);

      if (user === undefined || user.name !== username || user.pass !== password) {
        // Return 401 error if user/pass is incorrect or empty
        res.statusCode = 401;
        res.setHeader('WWW-Authenticate', 'Basic realm="Research tool"');
        res.end('Unauthorized');
      } else {
        next();
      }
     }
  });
};

app.js 文件:

var express = require('express');
var app = express();
var auth = require('./sources/auth.js');

// Run auth around app first
auth(app);

app.get('/route1', function(req, res) {
  res.render('pages/route1');
}

app.get('/route2', function(req, res) {
  res.render('pages/route2');
}

app.listen(port, function() {
  console.log('App listening on port: ' + port);
});

运行:node v6.11.1,express 4.13.4,basic-auth 1.1.0

【问题讨论】:

    标签: node.js express


    【解决方案1】:

    将用户名和密码硬编码在其中是非常不寻常的。更典型的是,用户名和(散列)密码存储在数据库中。然后当授权请求进来时,您使用用户名来获取密码,然后将两个密码相互比较。这样,一个身份验证中间件可以为任意数量的用户名/密码组合提供服务。

    也就是说,如果您真的需要两个单独的 auth 中间件,更好的方法是将所需的中间件插入到每个路由中。像这样的:

    auth.js

    const auth = require('basic-auth')
    
    const getAuthorizer = (name, pass) => (req, res, next) => {
      const user = auth(req)
      if (!user || user.name !== name || user.pass !== pass) {
        res.status(401).send('Unauthorized')
      } else {
        next()
      }
    }
    
    const admin = getAuthorizer('admin', 'supersecret')
    const user = getAuthorizer('user', '12345')
    
    module.exports = { admin, user }
    

    app.js

    const express = require('express')
    const app = express()
    const auth = require('./sources/auth')
    
    app.get('/route1', auth.admin, (req, res) => {
      res.render('pages/route1')
    })
    
    app.get('/route2', auth.user, (req, res) => {
      res.render('pages/route2')
    })
    
    app.listen(port, () => {
      console.log('App listening on port: ' + port)
    })
    

    【讨论】:

      【解决方案2】:

      您可以从 app.js 中的请求对象获取 url,因此您可以从文件或内部代码中包含路由 => 凭据映射。然后您将能够遍历地图以检查路线是否与传递的凭据数据匹配。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-03-13
        • 1970-01-01
        • 2010-09-30
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多