gpt4 book ai didi

node.js - 如何访问 basicAuth 内的快速路由

转载 作者:太空宇宙 更新时间:2023-11-04 01:04:56 25 4
gpt4 key购买 nike

我的 NodeJS 服务器,使用express,有一堆条目来指定各种路由:

app.post('list_streams.json',    auth, stream_handler.list_streams);
app.post('add_stream.json', auth, stream_handler.add_stream);
app.post('delete_stream.json', auth, stream_handler.delete_stream);
etc...

auth中间件是这样写的:

var auth = express.basicAuth(function(user, pass, callback) {     
user_handler.authenticate_user(user, pass, callback);
});

在 user_handler.authenticate_user() 函数内,执行对数据库的访问以验证用户。我想添加一些统计数据并跟踪特定用户执行的每次访问。我想在authenticate_user()函数中执行此操作,因为这是访问用户记录的数据库的地方,我可以使用相同的访问权限来更新用户记录中的统计信息,但我需要以某种方式传递authenticate_user() 的额外参数指定所执行的访问类型;路由本身或标识正在访问的路由的某些标记。我不知道该怎么做。 “req”在authenticate_user()函数中不可用。

谢谢你,加里

最佳答案

我不确定您需要什么可以通过您的authenticate_user函数轻松完成,因为它在任何用户第一次访问时每个 session 仅调用一次。

记录每个用户的所有访问的最佳方法是创建一个新的中间件函数,如本文末尾所述。

但是假设您只想记录用户身份验证,解决问题的一种方法是将express.basicAuth 替换为您自己的版本,该版本将回调函数绑定(bind)到express req 对象,如下所示:

var util=require('util'),
express=require('express'),
app=express(),
auth=basicAuth(function(username,password,next){
console.log('auth has access to req as "this": %s',util.inspect(this));
});

app.get('/',auth,function(req,res){
console.log('in request for "/", req is: %s',util.inspect(req));
res.send('SUCCESS');
});

app.listen(4000,function(){
console.log('running');
});

// Replacement for connect.basicAuth (as used by express)
// lifted from https://github.com/expressjs/basic-auth-connect

function unauthorized(res, realm) { // required by basicAuth
res.statusCode = 401;
res.setHeader('WWW-Authenticate', 'Basic realm="' + realm + '"');
res.end('Unauthorized');
}

function error(code, msg){ // required by basicAuth
var err = new Error(msg || http.STATUS_CODES[code]);
err.status = code;
return err;
}

// replacement basic auth which binds the callback to the "req" object
function basicAuth(callback, realm) {
var username, password;

// user / pass strings
if ('string' == typeof callback) {
username = callback;
password = realm;
if ('string' != typeof password) throw new Error('password argument required');
realm = arguments[2];
callback = function(user, pass){
return user == username && pass == password;
}
}

realm = realm || 'Authorization Required';

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

// 20140601 RR - !!NOTE!! bind callback to req
callback=callback.bind(req);

if (req.user) return next();
if (!authorization) return unauthorized(res, realm);

var parts = authorization.split(' ');

if (parts.length !== 2) return next(error(400));

var scheme = parts[0]
, credentials = new Buffer(parts[1], 'base64').toString()
, index = credentials.indexOf(':');

if ('Basic' != scheme || index < 0) return next(error(400));

var user = credentials.slice(0, index)
, pass = credentials.slice(index + 1);

// async
if (callback.length >= 3) {
callback(user, pass, function(err, user){
if (err || !user) return unauthorized(res, realm);
req.user = req.remoteUser = user;
next();
});
// sync
} else {
if (callback(user, pass)) {
req.user = req.remoteUser = user;
next();
} else {
unauthorized(res, realm);
}
}
}
}

如果您查看标有“!!NOTE!!”的行在上面,您将看到传递给新 basicAuth 函数的回调已绑定(bind)到 express 的 req 请求对象,这使得其 this 的概念成为对请求的引用。

现在您需要做的就是引用 this.url 来获取原始请求 URL 并记录它。

如上所述,需要注意的一件事是对 auth 的回调仅被调用以对用户进行一次身份验证。

后续请求已经设置了 req.user HTTP header 变量,因此允许请求通过,而无需调用身份验证回调。

这就是为什么记录特定用户的所有交互的最佳方法是在调用 auth 之后添加您自己的中间件,例如:

function logUser(req,res,next){

// since this middleware is called AFTER auth, the user is already authorized.
log.info('user "'+req.user+'" called url:'+req.url);

next(); // pass control to the next stage in fulfilling the request
}

app.get('/',auth,logUser,function(req,res){
...
});

关于node.js - 如何访问 basicAuth 内的快速路由,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23976965/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com