node.js Node 和 Express 4 的基本 HTTP 身份验证
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/23616371/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Basic HTTP authentication with Node and Express 4
提问by Dov
It looks like implementing basic HTTP authentication with Express v3 was trivial:
看起来使用 Express v3 实现基本的 HTTP 身份验证很简单:
app.use(express.basicAuth('username', 'password'));
Version 4 (I'm using 4.2) removed the basicAuthmiddleware, though, so I'm a little stuck. I have the following code, but it doesn't cause the browser to prompt the user for credentials, which is what I'd like (and what I imagine the old method did):
不过,版本 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();
}
});
采纳答案by Dov
I used the code for the original basicAuthto find the answer:
我使用原始代码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();
}
});
回答by Qwerty
Simple Basic Auth with vanilla JavaScript (ES6)
使用 vanilla JavaScript (ES6) 的简单基本身份验证
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] = Buffer.from(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
// -----------------------------------------------------------------------
})
note: This "middleware" can be used in any handler. Just remove next()and reverse the logic. See the 1-statementexample below, or the edit historyof this answer.
注意:这个“中间件”可以在任何处理程序中使用。只需删除next()并反转逻辑即可。请参阅下面的1 语句示例,或此答案的编辑历史记录。
Why?
为什么?
req.headers.authorizationcontains the value "Basic <base64 string>", but it can also be empty and we don't want it to fail, hence the weird combo of|| ''- Node doesn't know
atob()andbtoa(), hence theBuffer
req.headers.authorization包含值“Basic <base64 string>”,但它也可以为空,我们不希望它失败,因此奇怪的组合|| ''- Node 不知道
atob()andbtoa(),因此Buffer
ES6 -> ES5
ES6 -> ES5
constis just var.. sort of(x, y) => {...}is just function(x, y) {...}const [login, password] = ...split()is just two varassignments in one
const只是var...那种(x, y) => {...}只是function(x, y) {...}const [login, password] = ...split(),只不过是两个var在一个任务
source of inspiration (uses packages)
以上是一个 super simple旨在成为的超级简单示例super short超短且可快速部署到您的游乐场服务器。但正如评论中指出的那样,密码也可以包含冒号字符
::。正确地从b64authb64auth,您可以使用它。 // 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(/(.*?):(.*)/) || []
Basic auth in one statement
一份声明中的基本身份验证
...on the other hand, if you only ever use one or very few logins, this is the bare minimum you need: (you don't even need to parse the credentials at all)
...另一方面,如果您只使用一次或很少登录,这是您需要的最低限度:(您甚至根本不需要解析凭据)
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)
}
PS: do you need to have both "secure" and "public" paths? Consider using express.routerinstead.
PS:你需要同时拥有“安全”和“公共”路径吗?考虑express.router改用。
var securedRoutes = require('express').Router()
securedRoutes.use(/* auth-middleware from above */)
securedRoutes.get('path1', /* ... */)
app.use('/secure', securedRoutes)
app.get('public', /* ... */)
// example.com/public // no-auth
// example.com/secure/path1 // requires auth
回答by rsp
TL;DR:
特尔;博士:
? express.basicAuthis gone
? basic-auth-connectis deprecated
? basic-authdoesn't have any logic
? http-authis an overkill
? express-basic-authis what you want
? express.basicAuth没了
?basic-auth-connect已弃用
?basic-auth没有逻辑
?http-auth是矫枉过正
吗?express-basic-auth是你想要的
More info:
更多信息:
Since you're using Express then you can use the express-basic-authmiddleware.
由于您使用的是 Express,因此您可以使用express-basic-auth中间件。
See the docs:
查看文档:
Example:
例子:
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!
}));
回答by Brian Prodoehl
A lot of the middleware was pulled out of the Express core in v4, and put into separate modules. The basic auth module is here: https://github.com/expressjs/basic-auth-connect
很多中间件在 v4 中被从 Express 核心中拉出来,并放入单独的模块中。基本身份验证模块在这里:https: //github.com/expressjs/basic-auth-connect
Your example would just need to change to this:
您的示例只需要更改为:
var basicAuth = require('basic-auth-connect');
app.use(basicAuth('username', 'password'));
回答by WarsClon
I changed in express 4.0 the basic authentication with http-auth, the code is:
我在 express 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);
回答by Michael
There seems to be multiple modules to do that, some are deprecated.
似乎有多个模块可以做到这一点,有些已被弃用。
This one looks active:
https://github.com/jshttp/basic-auth
这个看起来很活跃:https:
//github.com/jshttp/basic-auth
Here's a use example:
这是一个使用示例:
// auth.js
var auth = require('basic-auth');
var admins = {
'[email protected]': { 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
Make sure you put the authmiddleware in the correct place, any middleware before that will not be authenticated.
确保将auth中间件放在正确的位置,在此之前的任何中间件都不会被验证。
回答by VIKAS KOHLI
We can implement the basic authorization without needing any module
我们可以实现基本授权,不需要任何模块
//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);
Source:- http://www.dotnetcurry.com/nodejs/1231/basic-authentication-using-nodejs
来源:- http://www.dotnetcurry.com/nodejs/1231/basic-authentication-using-nodejs
回答by Loourr
Express has removed this functionality and now recommends you use the basic-authlibrary.
Express 已删除此功能,现在建议您使用basic-auth库。
Here's an example of how to use:
以下是如何使用的示例:
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)
To send a request to this route you need to include an Authorization headerformatted for basic auth.
要向此路由发送请求,您需要包含一个为基本身份验证设置格式的Authorization 标头。
Sending a curl request first you must take the base64encoding of name:passor in this case aladdin:opensesamewhich is equal to YWxhZGRpbjpvcGVuc2VzYW1l
首先发送 curl 请求,您必须采用或 在这种情况下等于的base64编码name:passaladdin:opensesameYWxhZGRpbjpvcGVuc2VzYW1l
Your curl request will then look like:
您的 curl 请求将如下所示:
curl -H "Authorization: Basic YWxhZGRpbjpvcGVuc2VzYW1l" http://localhost:3000/

