使用原生 JavaScript (ES6) 实现简单的基础认证
app.use((req, res, next) => {
const auth = {login: 'yourlogin', password: 'yourpassword'}
const b64auth = (req.headers.authorization || '').split(' ')[1] || ''
const [login, password] = Buffer.from(b64auth, 'base64').toString().split(':')
if (login && password && login === auth.login && password === auth.password) {
return next()
}
res.set('WWW-Authenticate', 'Basic realm="401"')
res.status(401).send('Authentication required.')
})
注意:这个“中间件”可以在任何处理程序中使用。只需移除next()
并反转逻辑即可。请参见下面的1语句示例,或查看此答案的编辑历史记录。
为什么?
req.headers.authorization
包含值"Basic <base64字符串>
",但它也可能为空,我们不希望它失败,因此采用奇怪的||''
组合
- Node不知道
atob()
和btoa()
,因此使用Buffer
ES6 -> ES5
const
就是var
..差不多
(x, y) => {...}
就是function(x, y) {...}
const [login, password] = ...split()
就是两个var
赋值在一个语句中
启发来源(使用包)
上面是一个
超级简单的示例,旨在快速部署到您的游乐场服务器。但正如评论中指出的那样,密码也可能包含冒号字符
:
。为了正确从
b64auth中提取它,可以使用以下内容。
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)
一句话理解基本身份认证
......另一方面,如果您只使用一个或很少的登录,那么这是您所需要的最低限度:(您甚至无需解析凭据)
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
}
提示:你是否需要同时拥有“安全”和“公共”路径?考虑使用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
express-basic-auth
的文档中并不清楚如何将其应用于一个路由。 - Oleg Abrazhaev