Node.js 使用Node和Express 4进行基本HTTP身份验证
使用Express v3实现基本HTTP身份验证看起来很简单:Node.js 使用Node和Express 4进行基本HTTP身份验证,node.js,http,express,http-authentication,Node.js,Http,Express,Http Authentication,使用Express v3实现基本HTTP身份验证看起来很简单: app.use(express.basicAuth('username', 'password')); 但是,版本4(我使用的是4.2)删除了basicAuth中间件,所以我有点卡住了。我有以下代码,但它不会导致浏览器提示用户输入凭据,这正是我想要的(我想象旧方法会这样做): 我使用原始代码来找到答案: app.use(function(req, res, next) { var user = auth(req);
app.use(express.basicAuth('username', 'password'));
但是,版本4(我使用的是4.2)删除了basicAuth
中间件,所以我有点卡住了。我有以下代码,但它不会导致浏览器提示用户输入凭据,这正是我想要的(我想象旧方法会这样做):
我使用原始代码来找到答案:
app.use(function(req, res, next) {
var user = auth(req);
if (user === undefined || user['name'] !== 'username' || user['pass'] !== 'password') {
res.statusCode = 401;
res.setHeader('WWW-Authenticate', 'Basic realm="MyRealmName"');
res.end('Unauthorized');
} else {
next();
}
});
在v4中,许多中间件从Express核心中抽出,并放入单独的模块中。基本身份验证模块如下所示: 您的示例只需更改为:
var basicAuth = require('basic-auth-connect');
app.use(basicAuth('username', 'password'));
我在express 4.0中更改了基本身份验证,代码为:
var auth = require('http-auth');
var basic = auth.basic({
realm: "Web."
}, function (username, password, callback) { // Custom authentication method.
callback(username === "userName" && password === "password");
}
);
app.get('/the_url', auth.connect(basic), routes.theRoute);
似乎有多个模块可以做到这一点,有些模块已被弃用 这一个看起来很活跃:
下面是一个使用示例:
// auth.js
var auth = require('basic-auth');
var admins = {
'art@vandelay-ind.org': { password: 'pa$$w0rd!' },
};
module.exports = function(req, res, next) {
var user = auth(req);
if (!user || !admins[user.name] || admins[user.name].password !== user.pass) {
res.set('WWW-Authenticate', 'Basic realm="example"');
return res.status(401).send();
}
return next();
};
// app.js
var auth = require('./auth');
var express = require('express');
var app = express();
// ... some not authenticated middlewares
app.use(auth);
// ... some authenticated middlewares
确保将auth
中间件放在正确的位置,在此之前的任何中间件都不会经过身份验证。Simple Basic auth with vanilla JavaScript(ES6)
注意:这个“中间件”可以在任何处理程序中使用。只需删除next()
并反转逻辑即可。请参见下面的1-语句示例,或此答案的开头部分
为什么?
包含值“req.headers.authorization
”,但它也可以是空的,我们不希望它失败,因此出现了一个奇怪的组合Basic
- 节点不知道
和atob()
,因此btoa()
var
。。有点只是
函数(x,y){…}
在一个系统中只有两个
var
赋值
上面是一个超级简单的示例,它的设计意图是超级短,并且可以快速部署到您的游乐场服务器上。但正如评论中指出的,密码也可以包含冒号字符
:
。要从b64auth中正确提取它,可以使用以下命令
// parse login and password from headers
const b64auth = (req.headers.authorization || '').split(' ')[1] || ''
const strauth = Buffer.from(b64auth, 'base64').toString()
const splitIndex = strauth.indexOf(':')
const login = strauth.substring(0, splitIndex)
const password = strauth.substring(splitIndex + 1)
// using shorter regex by @adabru
// const [_, login, password] = strauth.match(/(.*?):(.*)/) || []
一条语句中的基本身份验证
…另一方面,如果您只使用一个或很少的登录,这是您需要的最低限度:(您甚至不需要解析凭据)
PS:您需要同时拥有“安全”和“公共”路径吗?考虑使用,
Express已删除此功能,现在建议您使用该库 下面是一个如何使用的示例:
var http = require('http')
var auth = require('basic-auth')
// Create server
var server = http.createServer(function (req, res) {
var credentials = auth(req)
if (!credentials || credentials.name !== 'aladdin' || credentials.pass !== 'opensesame') {
res.statusCode = 401
res.setHeader('WWW-Authenticate', 'Basic realm="example"')
res.end('Access denied')
} else {
res.end('Access granted')
}
})
// Listen
server.listen(3000)
要向该路由发送请求,您需要包含一个格式化的for basic auth
首先发送curl请求,您必须采用name:pass
的编码,或者在本例中为aladdin:opensesame
,它等于YWxhZGRpbjpvcGVuc2VzYW1l
然后,您的卷曲请求将如下所示:
curl -H "Authorization: Basic YWxhZGRpbjpvcGVuc2VzYW1l" http://localhost:3000/
我们可以在不需要任何模块的情况下实现基本授权
//1.
var http = require('http');
//2.
var credentials = {
userName: "vikas kohli",
password: "vikas123"
};
var realm = 'Basic Authentication';
//3.
function authenticationStatus(resp) {
resp.writeHead(401, { 'WWW-Authenticate': 'Basic realm="' + realm + '"' });
resp.end('Authorization is needed');
};
//4.
var server = http.createServer(function (request, response) {
var authentication, loginInfo;
//5.
if (!request.headers.authorization) {
authenticationStatus (response);
return;
}
//6.
authentication = request.headers.authorization.replace(/^Basic/, '');
//7.
authentication = (new Buffer(authentication, 'base64')).toString('utf8');
//8.
loginInfo = authentication.split(':');
//9.
if (loginInfo[0] === credentials.userName && loginInfo[1] === credentials.password) {
response.end('Great You are Authenticated...');
// now you call url by commenting the above line and pass the next() function
}else{
authenticationStatus (response);
}
});
server.listen(5050);
资料来源:-TL;博士:
☒ <代码>express.basicAuth不见了☒ <代码>基本身份验证连接已弃用
☒ <代码>基本身份验证没有任何逻辑
☒ <代码>http身份验证是一种过度杀伤力
☑ <代码>快速基本身份验证是您想要的 更多信息: 既然您使用的是Express,那么就可以使用
Express basic auth
中间件
见文件:
const app = require('express')();
const basicAuth = require('express-basic-auth');
app.use(basicAuth({
users: { admin: 'supersecret123' },
challenge: true // <--- needed to actually show the login dialog!
}));
const-app=require('express')();
const basicAuth=require('express-basic-auth');
应用程序使用(basicAuth)({
用户:{admin:'supersecret123'},
挑战:正确//此模块声称已被弃用(尽管它建议的替代方案似乎不令人满意)^^绝对不令人满意,因为在密密麻麻的未记录文档中。作为中间件使用的示例为零,这可能很好,但调用不可用。他们给出的示例非常通用,但不适用于使用信息。是的,这一示例已被弃用,虽然推荐的示例文档数量较少,但代码非常简单,我已经介绍了如何使用e整个模块如何存在的basic auth
库基于将密码以明文形式放在代码中??至少通过在base64中进行比较来模糊它似乎稍微好一点。此模块被认为已弃用,请改用(相同的api,因此答案仍然适用)实际上,我支持“基本身份验证连接”,名称不好,但从功能上看,它比“基本身份验证”好。后者所做的只是解析授权头。您仍然必须自己实现协议(也称为发送正确的头)太好了!谢谢你。这很有效,而且解释得很好。我试过了,但它一直要求我通过连续循环登录。最好的…:)不要使用。split(':')
,因为它会阻塞至少包含一个冒号的密码。这样的密码根据有效。你也可以使用RegExpconst[\uz,login,password]=strauth.match(/(.*):(.*)/)|【】
用于冒号部分。使用!==
比较密码容易受到定时攻击。请确保使用固定时间字符串比较。对于字符串
使用缓冲区.from()//或对于数字
使用缓冲区.alloc()//作为缓冲区()
由于安全问题而被弃用。这实际上是即插即用。卓越。无耻的插件:我维护了一个相当流行的模块,使其变得简单,并具有您需要的最标准的功能:我最近分叉了@LionC的包,因为我必须对其进行调整(启用上下文感知授权程序)在公司项目的极短时间内:我花了一段时间才弄清楚挑战:真的option@VitaliiZurian很好的一点-我把它添加到了答案中。谢谢你指出它。@rsp你知道如何仅将它应用于特定的路由吗?如果你不想添加其他依赖项,用h编写基本的身份验证非常容易还有一句话…客户端url是什么样子的?希望它能解决这个问题,但请添加对代码的解释,这样用户就能完全理解他/她真正想要的。
var http = require('http')
var auth = require('basic-auth')
// Create server
var server = http.createServer(function (req, res) {
var credentials = auth(req)
if (!credentials || credentials.name !== 'aladdin' || credentials.pass !== 'opensesame') {
res.statusCode = 401
res.setHeader('WWW-Authenticate', 'Basic realm="example"')
res.end('Access denied')
} else {
res.end('Access granted')
}
})
// Listen
server.listen(3000)
curl -H "Authorization: Basic YWxhZGRpbjpvcGVuc2VzYW1l" http://localhost:3000/
//1.
var http = require('http');
//2.
var credentials = {
userName: "vikas kohli",
password: "vikas123"
};
var realm = 'Basic Authentication';
//3.
function authenticationStatus(resp) {
resp.writeHead(401, { 'WWW-Authenticate': 'Basic realm="' + realm + '"' });
resp.end('Authorization is needed');
};
//4.
var server = http.createServer(function (request, response) {
var authentication, loginInfo;
//5.
if (!request.headers.authorization) {
authenticationStatus (response);
return;
}
//6.
authentication = request.headers.authorization.replace(/^Basic/, '');
//7.
authentication = (new Buffer(authentication, 'base64')).toString('utf8');
//8.
loginInfo = authentication.split(':');
//9.
if (loginInfo[0] === credentials.userName && loginInfo[1] === credentials.password) {
response.end('Great You are Authenticated...');
// now you call url by commenting the above line and pass the next() function
}else{
authenticationStatus (response);
}
});
server.listen(5050);
const app = require('express')();
const basicAuth = require('express-basic-auth');
app.use(basicAuth({
users: { admin: 'supersecret123' },
challenge: true // <--- needed to actually show the login dialog!
}));
function auth (req, res, next) {
console.log(req.headers);
var authHeader = req.headers.authorization;
if (!authHeader) {
var err = new Error('You are not authenticated!');
res.setHeader('WWW-Authenticate', 'Basic');
err.status = 401;
next(err);
return;
}
var auth = new Buffer.from(authHeader.split(' ')[1], 'base64').toString().split(':');
var user = auth[0];
var pass = auth[1];
if (user == 'admin' && pass == 'password') {
next(); // authorized
} else {
var err = new Error('You are not authenticated!');
res.setHeader('WWW-Authenticate', 'Basic');
err.status = 401;
next(err);
}
}
app.use(auth);