我正在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);
});
运行:节点v6.11.1,表达4.13.4,basic-auth 1.1.0
答案 0 :(得分:0)
您可以从app.js中的请求对象获取网址,这样您就可以包含route =>凭证映射来自文件或内部代码。然后,您将能够迭代map以检查路由是否匹配传递的凭证数据。
答案 1 :(得分:0)
您使用硬编码的用户名和密码非常不寻常。更典型的是,用户名和(哈希)密码存储在数据库中。然后,当授权请求进入时,您使用用户名来获取密码,并将两个密码相互比较。通过这种方式,一个auth中间件可以为任意数量的用户名/密码组合提供服务。
也就是说,如果真的需要两个独立的auth中间件,更好的方法是将所需的中间件插入到每个路由中。像这样:
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 }
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)
})