Basic HTTP authentication with Node and Express 4
使用Express v3实施基本的HTTP身份验证似乎很简单:
1 | app.use(express.basicAuth('username', 'password')); |
但是,版本4(我使用的是4.2)删除了
1 2 3 4 5 6 7 8 9 10 | 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(); } }); |
使用香草JavaScript(ES6)的简单基本身份验证
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | 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 // ----------------------------------------------------------------------- }) |
注意:此"中间件"可以在任何处理程序中使用。只需删除
为什么?
-
req.headers.authorization 包含值"Basic ",但它也可以为空,我们不希望它失败,因此|| '' 的组合很奇怪 -
节点不知道
atob() 和btoa() ,因此不知道Buffer
ES6-> ES5
灵感来源(使用软件包)
上面是一个非常简单的示例,旨在使它非常短并且可以快速部署到您的游乐场服务器。但正如注释中指出的那样,密码也可以包含冒号
1 2 3 4 5 6 7 8 9 | // 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(/(.*?):(.*)/) || [] |
一条语句中的基本身份验证
...另一方面,如果您只使用一次或很少的登录,这是您所需要的最低要求:(您甚至根本不需要解析凭据)
1 2 3 4 5 6 7 8 9 10 11 12 13 | 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:您需要同时具有"安全"和"公共"路径吗?考虑改用
1 2 3 4 5 6 7 8 9 10 | 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 |
TL; DR:
?
?
吗?
吗?
更多信息:
由于使用的是Express,因此可以使用
参见文档:
- https://www.npmjs.com/package/express-basic-auth
例:
1 2 3 4 5 6 7 | 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! })); |
许多中间件都从v4的Express核心中抽出,并放入单独的模块中。基本的身份验证模块在这里:https://github.com/expressjs/basic-auth-connect
您的示例只需更改为:
1 2 | var basicAuth = require('basic-auth-connect'); app.use(basicAuth('username', 'password')); |
我使用原始
1 2 3 4 5 6 7 8 9 10 11 | 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(); } }); |
我在express 4.0中使用http-auth更改了基本身份验证,代码为:
1 2 3 4 5 6 7 8 9 10 | 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); |
似乎有多个模块可以执行此操作,其中一些已弃用。
这个看起来很活跃:
https://github.com/jshttp/basic-auth
这是一个使用示例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 | // 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 |
确保将
我们可以实现基本授权,而无需任何模块
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 | //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); |
资料来源:-http://www.dotnetcurry.com/nodejs/1231/basic-authentication-using-nodejs
Express已删除此功能,现在建议您使用basic-auth库。
以下是使用方法的示例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | 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请求将如下所示:
1 | curl -H"Authorization: Basic YWxhZGRpbjpvcGVuc2VzYW1l" http://localhost:3000/ |