基本 HTTP 身份验证,除了使用 Express 的 Node 的 localhost

Basic HTTP authentication except for localhost with Node using Express

我正在尝试为非 运行 在本地主机上的客户端使用 Express 为 Node 应用程序设置身份验证。

基本上,我有一个 RPi 运行 节点,我正在使用 Chromium 作为设备的 GUI。问题是您只需从网络上的任何浏览器输入设备的 IP 地址,它就会提供相同的内容。这在某些情况下是需要的,但我想用密码保护它。

这是我使用 express-basic-auth 的设置:

const express = require('express'),
      basicAuth = require('express-basic-auth');

const app = module.exports = express();
const server = require('http').createServer(app);

// Hook Socket.io into Express
const io = require('socket.io').listen(server);

// Configuration
app.use( basicAuth(
{
  users: { admin: 'secret' },
  challenge: true
}))

app.use( express.static('./my_path/') );

// Socket.io Communication
io.sockets.on('connection', require('./modules/socket'));

// Start server
server.listen(3000, () => console.log("Express server listening on port %d in %s mode", server.address().port, app.settings.env));

这可行,但是,我不想对本地主机进行身份验证。

我可以通过这样的请求获取主机:

app.use( ( req ) =>
{
  debug( req.headers.host );
})

我对 Node 和 Express 的了解还不够,无法将它们放在一起。

可能 express-basic-auth 中缺少某些东西,或者我可以使用不同的授权中间件。

我认为最简单的解决方案是在您的应用程序前面设置一个 Web 服务器来管理 HTTP 身份验证。然后当你在本地时,你可以绕过网络服务器并直接点击应用程序。

https://docs.nginx.com/nginx/admin-guide/security-controls/configuring-http-basic-authentication/

否则,您将不得不编写代码来检查入站请求是否来自您的本地设备,可能是通过检查请求中的 IP 地址并将其与您当前分配的 IP 地址进行比较。

试试下面的代码:

// Configuration
(req, res, next) => {
  if(req.headers.host != 'localhost')
    app.use({
      users: { admin: 'secret' },
      challenge: true
    });
  next();
}

当本地主机尝试使用该网站时,将 'localhost' 更改为任何 req.headers.host 状态。

basicAuth() 中的三重点代表您在那里拥有的所有其余代码。 next() 用于告诉代码继续前进。

它有助于可视化是否每个请求都通过设置文件到达后端 "falls"。您添加到此文件的每件事都像请求失败的另一件事一样运行。

我最终只使用了 basic-auth 并设置了 WWW-Authenticate 响应 header。

const express = require('express'),
      basicAuth = require('basic-auth');

const app = module.exports = express();
const server = require('http').createServer(app);

// Hook Socket.io into Express
const io = require('socket.io').listen(server);

// Configuration
app.use( ( req, res, next ) =>
{
  // Require authentication when the connection is not from localhost.
  if ( req.headers.host == 'localhost:3000' )
    return next();

  var authentication = basicAuth( req );

  if ( authentication && authentication.name == 'admin' && authentication.pass == 'secret' )
    return next();

  res.set('WWW-Authenticate', 'Basic');

  return res.status(401).send();
})

app.use( express.static('./my_path/') );

// Socket.io Communication
io.sockets.on('connection', require('./modules/socket'));

// Start server
server.listen(3000, () => console.log("Express server listening on port %d in %s mode", server.address().port, app.settings.env));