为网站的内部页面添加Basic认证

本文介绍如何在Node.js中使用connect-basic-auth模块实现基本的身份验证功能,包括安装配置及如何仅对特定页面启用验证。

我为网站添加了Graphite,awstats的统计,所以就需要做一个页面,存放一些链接,以方便访问。但是这个页面不希望被其他人访问到,所以就需要做一些简单的验证--Basic Auth。

Nodejs的验证模块,比较有名的是connect-auth,不过这个太重量级的,所以我用的是很有针对性的,轻量级的认证模块,connect-basic-auth。这个模块只有一个源文件。。很简单。。

好,闲话少说。


1) 安装:npm install connect-basic-auth --save。

2) 从名字就可以看出,他是ExpressJs/ConnectJs的一个中间件,这是他的所有源代码:

module.exports = function (callback, realm) {
    if (!callback || typeof callback != 'function') {
        throw new Error('You must provide a function ' +
        'callback as the first parameter');
    }

    realm = realm ? realm : 'Authorization required.';

    function unauthorized(res, sendResponse) {
        res.statusCode = 401;
        res.setHeader('WWW-Authenticate', 'Basic realm="' + realm + '"');

        if (sendResponse) {
            res.end('Unauthorized');
        }
    }

    return function(req, res, next) {
        req.requireAuthorization = function(req, res, next) {
            var authorization = req.headers.authorization;

            if (req.remoteUser) return next();
            if (!authorization) return unauthorized(res, true);

            var parts = authorization.split(' ');
            var scheme = parts[0];
            if ('Basic' != scheme) {
                return next(new Error('Authorization header ' +
                'does not have the correct scheme. \'Basic\' ' +
                'scheme was expected.'));
            }

            var _credentials = new Buffer(parts[1], 'base64').toString().split(':');

            var credentials = { username: _credentials[0],
                                password: _credentials[1] };

            callback(credentials, req, res, function(err) {
                if (err) {
                    unauthorized(res);
                    next(err);
                    return;
                }

                req.remoteUser = credentials.username;
                next();
            });
        };
        next();
    };
};

这代码其实和connect-auth差不多,不知道有没有渊源。他其实很简单,通过module.export返回一个函数,运行这个函数就可以获得中间件需要的函数了。我又在他的基础上,封装了验证的逻辑,用户名密码我是明文的,而且hard-coding,用basic-auth就是求简单,而且网站是给内部使用的,所以就不矫情了(middlewares.js):

var should = require("should")
  , basicAuth = require('connect-basic-auth');

// Validate user's password
exports.basicAuth = function () {
    return basicAuth(function (credentials, req, res, next) {
        if (credentials && credentials.username == "cer" && credentials.password == "site") {
            next();
        }
        else {
            if (!credentials) console.log("credentials not provided");
            if (credentials && credentials.username) console.log("credentials-username:" + credentials.username);
            if (credentials && credentials.password) console.log("credentials-password:" + credentials.username);
            next("Unautherized!");
        }
    });
}


这个是app.js,使用了那个中间件:

var express = require('express')
  , http = require('http')
  , path = require('path')
  , util = require('util')
  , middlewares = require('./middlewares');

var app = express();

app.configure(function () {
    app.set('env', 'production');
    app.set('port', process.env.PORT || 80);
    app.set('views', __dirname + '/views');
    app.set('view engine', 'ejs');
    app.use(express.favicon());
    app.use(express.logger('dev'));
    app.use(express.bodyParser());
    app.use(express.methodOverride());
    app.use(middlewares.basicAuth());
    app.use(app.router);
    app.use(express.static(path.join(__dirname, 'public')));
    app.use(express.errorHandler());
});

注意,上面那个use,没有实际作用的,看上面源代码就知道,他不过是添加了一个req.requireAuthorization()的成员函数,所以,只有你显示调用这个函数,才会真正起到验证效果!这个是非常棒的!也就是说,你可以选择性的为某些页面添加验证,其他页面还是公开访问!这正是我所需要的~。看代码:

var _ = require('underscore')
  , fs = require('fs')
  , spawn = require('child_process').spawn
  , util = require('util')
  , should = require('should')
  , async = require('async');

///////////////////////////
// Exports
///////////////////////////

var g_app;

exports.initRoutes = function (app) {
    g_app = app;
    var pageRequests = [
        { method: "get", request: /^\/internal(\/.*)?/, handler: "auth" },
        { method: "get", request: "/internal", handler: "index" },
        { method: "get", request: "/internal/visisted_users", handler: "visistedUsers" },
        { method: "get", request: "/internal/integration_test", handler: "integrationTest" },
    ];

    _.each(pageRequests, function (pageRequest) {

        var request, handler, method;
        request = pageRequest.request;
        handler = exports[pageRequest.handler];
        method = app[pageRequest.method] || app.get;
        method.call(app, request, handler);
    });
}

exports.auth = function (req, res, next) {
    req.requireAuthorization(req, res, next);
}

exports.index = function (req, res, next) {
    res.render("page_internal");
}

exports.visistedUsers = function (req, res) {
    ......
}

exports.integrationTest = function (req, res) {
    ......
}

在路由的最上面,我用正则表达式加了一个验证auth的hanlder(因为回调函数有next参数,也算是中间件吧),凡是/internal/xxx的都需要经过验证。auth()的实现很简单,就是调用req.requireAuthorization(),看源代码就知道,他首先检查客户端有没有Authorization首部,没有的话,回送一个401(需要验证),这个时候浏览器就会弹出一个验证框,让你输入用户名密码,然后再次发送请求。有的话,就调用最初设置进去的回调函数,让你验证用户的credentical信息,成功你就调用next(),继续调用下一个handler,反之调用next("error")来结束路由。

所以,整体代码还是很简单的。



-----------------------------------------

更新:因为iisnode托管,启用了域认证,所以basic auth不成功(当然不托管能行)






<think>嗯,用户问的是如何在Nginx中配置系统管理员权限或管理设置。我需要先理解他们的需求。可能他们想限制某些敏感页面的访问,比如后台管理界面,只有管理员才能进入。这时候应该想到使用访问控制,比如基于IP的限制或者密码认证。 首先,权限控制通常有两种方式:IP白名单和密码认证。IP白名单可以通过Nginx的allow和deny指令来实现,只允许特定的IP访问。而密码认证则需要创建用户密码文件,使用auth_basic模块。 然后,用户提到的“系统管理员权限”可能还涉及到错误页面的自定义,比如显示特定的错误信息给管理员。比如404或者50x错误页面,可以引用中的server上下文配置错误页面,这样不同的虚拟主机可以有自定义的错误提示。 接下来,要考虑到用户可能对Nginx配置不太熟悉,需要给出具体的步骤。比如创建密码文件要用htpasswd命令,配置location块来应用认证,还要检查配置文件语法是否正确,最后重启服务。这些步骤在引用[2]和引用[1]里有提到,比如使用sudo nginx -t检查配置,以及如何设置auth_basic。 另外,用户可能需要多因素认证,比如同时使用IP限制和密码认证,这样更安全。这时候需要在location块里同时设置allow/deny和auth_basic指令。 还有,关于权限问题,引用[1]提到要使用sudo执行命令,避免权限不足导致配置失败。同时,检查错误日志也是关键,帮助排除启动问题。 最后,确保回答结构清晰,分步骤说明,并且给出示例配置,方便用户直接套用。可能还需要提醒用户替换示例中的路径和密码文件名为实际使用的名称,以及生成密码时的注意事项,比如使用-c参数会覆盖文件,所以要小心操作。 相关问题部分需要考虑用户可能进一步的问题,比如如何自动化密码管理,或者如何处理动态IP的情况,以及如何结合防火墙增强安全性。这样能帮助用户更全面地管理他们的Nginx配置。</think>### 如何在 Nginx 中配置管理员权限或管理设置 在 Nginx 中配置管理员权限或管理设置,主要通过 **访问控制** 和 **身份验证** 实现,具体分为以下步骤: --- #### 一、基于 IP 地址的访问控制 **适用场景**:限制管理员后台仅允许特定 IP 访问。 1. 编辑 Nginx 配置文件(如站点配置文件 `/etc/nginx/sites-available/example.com`) ```nginx server { listen 80; server_name example.com; # 管理员后台路径 location /admin { allow 192.168.1.100; # 允许的 IP deny all; # 拒绝其他 IP try_files $uri $uri/ =404; } } ``` 2. 检查配置语法并重启 Nginx: ```bash sudo nginx -t # 验证配置[^1] sudo systemctl restart nginx ``` --- #### 二、密码认证配置 **适用场景**:为管理界面添加用户名/密码验证。 1. 使用 `htpasswd` 创建密码文件: ```bash sudo apt-get install apache2-utils # 安装工具 sudo htpasswd -c /etc/nginx/.admin_passwd admin_user # 生成文件[^4] ``` 2. 在 Nginx 配置中启用认证: ```nginx location /admin { auth_basic "Admin Area"; # 提示信息 auth_basic_user_file /etc/nginx/.admin_passwd; # 密码文件路径[^2] try_files $uri $uri/ =404; } ``` --- #### 三、组合使用 IP 限制与密码认证 ```nginx location /admin { allow 192.168.1.100; deny all; auth_basic "Admin Area"; auth_basic_user_file /etc/nginx/.admin_passwd; } ``` --- #### 四、自定义管理员错误页面 为管理员界面配置专属错误提示(如 403/404): ```nginx server { error_page 403 /admin_403.html; location = /admin_403.html { internal; # 仅限内部访问[^3] } } ``` --- #### 注意事项 1. **权限问题**:确保密码文件路径和 Nginx 进程权限匹配(通常属主为 `www-data`)。 2. **日志调试**:若配置失败,检查 `/var/log/nginx/error.log` 定位问题[^1]。 3. **密码安全**:定期更新密码文件,避免使用弱密码。 ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值