使用Express v3实现基本的HTTP身份验证看起来很简单:
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.writeHead(401, 'Access invalid for user', {'Content-Type' : 'text/plain'});
res.end('Invalid credentials');
} else {
next();
}
});
答案 0 :(得分:74)
app.use((req, res, next) => {
// -----------------------------------------------------------------------
// authentication middleware
const auth = {login: 'yourlogin', password: 'yourpassword'} // change this
// parse login and password from headers
const b64auth = (req.headers.authorization || '').split(' ')[1] || ''
const [login, password] = new Buffer(b64auth, 'base64').toString().split(':')
// Verify login and password are set and correct
if (login && password && login === auth.login && password === auth.password) {
// Access granted...
return next()
}
// Access denied...
res.set('WWW-Authenticate', 'Basic realm="401"') // change this
res.status(401).send('Authentication required.') // custom message
// -----------------------------------------------------------------------
})
注意:这个"中间件"可以在任何处理程序中使用。只需删除next()
并反转逻辑。请参阅下面的 1-statement 示例或此答案的edit history。
req.headers.authorization
包含值&#34; Basic <base64 string>
&#34;,但它也可以为空,我们不希望它失败,因此{{{{{{ 1}} || ''
和atob()
,因此Buffer
const
只是btoa()
..有点像
(x, y) => {...}
只是var
const [login, password] = ...split()
在一个
function(x, y) {...}
分配
source of inspiration (uses packages)
<小时/> 以上是超级简单示例,旨在超短并可快速部署到您的游乐场服务器。但正如评论中指出的那样,密码也可以包含冒号字符
var
。要从 b64auth 中正确提取它,您可以使用它。
:
...另一方面,如果你只使用一次或几次登录,这是你需要的最低限度:(你根本不需要解析凭证)< / em>的
// parse login and password from headers
const b64auth = (req.headers.authorization || '').split(' ')[1] || ''
const strauth = new Buffer(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:你需要同时拥有&#34; secure&#34;和#34;公共&#34;路径?请考虑使用express.router
代替。
function (req, res) {
//btoa('yourlogin:yourpassword') -> "eW91cmxvZ2luOnlvdXJwYXNzd29yZA=="
//btoa('otherlogin:otherpassword') -> "b3RoZXJsb2dpbjpvdGhlcnBhc3N3b3Jk"
// Verify credentials
if ( req.headers.authorization !== 'Basic eW91cmxvZ2luOnlvdXJwYXNzd29yZA=='
&& req.headers.authorization !== 'Basic b3RoZXJsb2dpbjpvdGhlcnBhc3N3b3Jk')
return res.status(401).send('Authentication required.') // Access denied.
// Access granted...
res.send('hello world')
// or call next() if you use it as middleware (as snippet #1)
}
答案 1 :(得分:58)
许多中间件在v4中被拉出了Express核心,并被放入了单独的模块中。基本身份验证模块位于:https://github.com/expressjs/basic-auth-connect
您的示例只需要更改为:
var basicAuth = require('basic-auth-connect');
app.use(basicAuth('username', 'password'));
答案 2 :(得分:38)
express.basicAuth
已消失☒basic-auth-connect
已弃用basic-auth
没有任何逻辑http-auth
是过度杀伤☑express-basic-auth
就是你想要的由于您使用的是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!
}));
答案 3 :(得分:33)
我使用原始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();
}
});
答案 4 :(得分:32)
我在快递4.0中使用http-auth更改了基本身份验证,代码为:
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);
答案 5 :(得分:19)
似乎有多个模块可以做到这一点,有些模块已被弃用。
这个看起来很活跃:
https://github.com/jshttp/basic-auth
这是一个使用示例:
// 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
中间件放在正确的位置,之前的任何中间件都不会通过身份验证。
答案 6 :(得分:4)
我们可以在不需要任何模块的情况下实施基本授权
null
来源: - http://www.dotnetcurry.com/nodejs/1231/basic-authentication-using-nodejs
答案 7 :(得分:1)
Express已删除此功能,现在建议您使用basic-auth库。
以下是如何使用的示例:
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)
要向此路线发送请求,您需要包含格式化为基本身份验证的Authorization header。
首先发送卷曲请求您必须采用name:pass
的{{3}}编码,或者aladdin:opensesame
YWxhZGRpbjpvcGVuc2VzYW1l
等于 curl -H "Authorization: Basic YWxhZGRpbjpvcGVuc2VzYW1l" http://localhost:3000/
您的卷曲请求将如下所示:
{{1}}
答案 8 :(得分:0)
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);