@78nine/polka-basic-auth 中文文档教程
polka-basic-auth
这只是 Polka 的一个端口……一些小的改变让它工作……
所有的功劳都归于原作者……因此……下面的原始描述……
您只需要将包的名称更改为 @79nine/polka -基本认证
;)
express-basic-auth
简单插件& 为 Express 播放 HTTP 基本身份验证中间件。
How to install
只需运行
npm install express-basic-auth
How to use
该模块将导出一个函数,您可以使用选项对象调用该函数 获取中间件:
const app = require('express')()
const basicAuth = require('express-basic-auth')
app.use(basicAuth({
users: { 'admin': 'supersecret' }
}))
中间件现在将检查传入的请求以匹配凭据 <代码>管理员:超级机密。
中间件将检查传入的基本身份验证请求(Authorization
) 标头,解析它并检查凭据是否合法。 如果有的话 凭据,auth
属性将添加到请求中,包含 具有 user
和 password
属性的对象,其中填充了凭据, 不管他们是否合法。
如果发现请求未被授权,它将以 HTTP 401 响应 和一个可配置的主体(默认为空)。
Static Users
如果您只是想针对一个或多个静态凭据检查基本身份验证, 您可以在 users
选项中传递这些凭据:
app.use(basicAuth({
users: {
'admin': 'supersecret',
'adam': 'password1234',
'eve': 'asdfghjkl',
}
}))
中间件将检查传入的请求是否具有基本的身份验证标头匹配 三个通过的凭据之一。
Custom authorization
或者,您可以传递自己的 authorizer
函数,以检查凭据 随你怎么便。 它将使用用户名和密码调用,预计 返回 true
或 false
以指示凭据是否已获批准。
使用您自己的授权器
时,确保不使用标准字符串比较(==
/ ===
) 将用户输入与秘密凭据进行比较时,因为这会使您容易受到攻击 定时攻击。 使用提供的 safeCompare
代替函数 - 始终提供用户输入作为其第一个参数。 还要确保按位使用 逻辑运算符(|
和 &
)而不是标准运算符(||
和 &&
)出于同样的原因,作为 标准的使用快捷方式。
app.use(basicAuth( { authorizer: myAuthorizer } ))
function myAuthorizer(username, password) {
const userMatches = basicAuth.safeCompare(username, 'customuser')
const passwordMatches = basicAuth.safeCompare(password, 'custompassword')
return userMatches & passwordMatches
}
这将使用凭据“customuser:custompassword”授权所有请求。 在实际的应用程序中,您可能会改为查找一些数据;-)您可以做任何您想做的事 想要自定义授权者,只需在最后返回 true
或 false
并注意时间安排 攻击。
Custom Async Authorization
请注意,上面的 authorizer
函数应该是同步的。 这是 默认行为,您可以在选项对象中传递 authorizeAsync: true
来指示 您的授权方是异步的。 在这种情况下,它将传递一个回调 作为第三个参数,预计将由标准节点约定调用 有一个错误和一个布尔值来指示凭据是否已被批准。 让我们再次查看同一个授权方,但这次是异步的:
app.use(basicAuth({
authorizer: myAsyncAuthorizer,
authorizeAsync: true,
}))
function myAsyncAuthorizer(username, password, cb) {
if (username.startsWith('A') & password.startsWith('secret'))
return cb(null, true)
else
return cb(null, false)
}
Unauthorized Response Body
默认情况下,未授权响应的响应主体将为空。 它可以 使用 unauthorizedResponse
选项进行配置。 你可以通过一个 静态响应或一个函数,它通过了明确的请求对象并且是 期望返回响应主体。 如果响应主体是一个字符串,它将 按原样使用,否则它将作为 JSON 发送:
app.use(basicAuth({
users: { 'Foo': 'bar' },
unauthorizedResponse: getUnauthorizedResponse
}))
function getUnauthorizedResponse(req) {
return req.auth
? ('Credentials ' + req.auth.user + ':' + req.auth.password + ' rejected')
: 'No credentials provided'
}
Challenge
默认情况下,中间件不会添加 WWW-Authenticate
挑战标头到 未经授权的请求的响应。 您可以通过添加 challenge: true
来启用它 到选项对象。 这将导致大多数浏览器显示弹出窗口以输入 未经授权的响应的凭据。 您可以设置领域(领域 标识系统以进行身份验证,并可由客户端用于保存 凭据)通过传递静态字符串或获取的函数来挑战 传递了请求对象并有望返回挑战:
app.use(basicAuth({
users: { 'someuser': 'somepassword' },
challenge: true,
realm: 'Imb4T3st4pp',
}))
Try it
存储库包含一个 example.js
,您可以运行它来尝试 中间件。 要使用它,只需将它放在某处(或将其留在原处),运行
npm install express express-basic-auth
node example.js
这将启动一个侦听端口 8080 的小型快速服务器。只需查看文件, 尝试请求并尝试各种选项。
TypeScript usage
声明文件与库捆绑在一起。 您不必安装 @types/
包。
import * as basicAuth from 'express-basic-auth'
:bulb: 使用 req.auth
express-basic-auth 将 req.auth
设置为包含授权凭据的对象,如 { user : 'admin', 密码: 'supersecret'
.
为了在 TypeScript 中使用 req.auth
属性而不会出现未知属性错误,请使用协方差来向下转换请求类型
app.use(basicAuth(options), (req: basicAuth.IBasicAuthedRequest, res, next) => {
res.end(`Welcome ${req.auth.user} (your password is ${req.auth.password})`)
next()
})
::bulb: 关于同步授权者类型推断的注释
由于某些 TypeScript 的类型系统限制,无法推断同步授权方的参数类型。 例如,在异步授权器上,可以正确推断三个参数:
basicAuth({
authorizeAsync: true,
authorizer: (user, password, authorize) => authorize(null, password == 'secret'),
})
但是,在同步授权器上,您必须自己输入参数:
basicAuth({
authorizer: (user: string, password: string) => (password == 'secret')
})
Tests
example.js
中的案例也用于自动化测试。 所以如果你想要
贡献或只是确保包仍然有效,只需运行:
npm test
polka-basic-auth
This is just a port to Polka… some minor changes to make it work…
All the credit goes to the original author… hence… the original description below…
You only need to change a name of the package to @79nine/polka-basic-auth
;)
express-basic-auth
Simple plug & play HTTP basic auth middleware for Express.
How to install
Just run
npm install express-basic-auth
How to use
The module will export a function, that you can call with an options object to get the middleware:
const app = require('express')()
const basicAuth = require('express-basic-auth')
app.use(basicAuth({
users: { 'admin': 'supersecret' }
}))
The middleware will now check incoming requests to match the credentials admin:supersecret
.
The middleware will check incoming requests for a basic auth (Authorization
) header, parse it and check if the credentials are legit. If there are any credentials, an auth
property will be added to the request, containing an object with user
and password
properties, filled with the credentials, no matter if they are legit or not.
If a request is found to not be authorized, it will respond with HTTP 401 and a configurable body (default empty).
Static Users
If you simply want to check basic auth against one or multiple static credentials, you can pass those credentials in the users
option:
app.use(basicAuth({
users: {
'admin': 'supersecret',
'adam': 'password1234',
'eve': 'asdfghjkl',
}
}))
The middleware will check incoming requests to have a basic auth header matching one of the three passed credentials.
Custom authorization
Alternatively, you can pass your own authorizer
function, to check the credentials however you want. It will be called with a username and password and is expected to return true
or false
to indicate that the credentials were approved or not.
When using your own authorizer
, make sure not to use standard string comparison (==
/ ===
) when comparing user input with secret credentials, as that would make you vulnerable against timing attacks. Use the provided safeCompare
function instead - always provide the user input as its first argument. Also make sure to use bitwise logic operators (|
and &
) instead of the standard ones (||
and &&
) for the same reason, as the standard ones use shortcuts.
app.use(basicAuth( { authorizer: myAuthorizer } ))
function myAuthorizer(username, password) {
const userMatches = basicAuth.safeCompare(username, 'customuser')
const passwordMatches = basicAuth.safeCompare(password, 'custompassword')
return userMatches & passwordMatches
}
This will authorize all requests with the credentials 'customuser:custompassword'. In an actual application you would likely look up some data instead ;-) You can do whatever you want in custom authorizers, just return true
or false
in the end and stay aware of timing attacks.
Custom Async Authorization
Note that the authorizer
function above is expected to be synchronous. This is the default behavior, you can pass authorizeAsync: true
in the options object to indicate that your authorizer is asynchronous. In this case it will be passed a callback as the third parameter, which is expected to be called by standard node convention with an error and a boolean to indicate if the credentials have been approved or not. Let's look at the same authorizer again, but this time asynchronous:
app.use(basicAuth({
authorizer: myAsyncAuthorizer,
authorizeAsync: true,
}))
function myAsyncAuthorizer(username, password, cb) {
if (username.startsWith('A') & password.startsWith('secret'))
return cb(null, true)
else
return cb(null, false)
}
Unauthorized Response Body
Per default, the response body for unauthorized responses will be empty. It can be configured using the unauthorizedResponse
option. You can either pass a static response or a function that gets passed the express request object and is expected to return the response body. If the response body is a string, it will be used as-is, otherwise it will be sent as JSON:
app.use(basicAuth({
users: { 'Foo': 'bar' },
unauthorizedResponse: getUnauthorizedResponse
}))
function getUnauthorizedResponse(req) {
return req.auth
? ('Credentials ' + req.auth.user + ':' + req.auth.password + ' rejected')
: 'No credentials provided'
}
Challenge
Per default the middleware will not add a WWW-Authenticate
challenge header to responses of unauthorized requests. You can enable that by adding challenge: true
to the options object. This will cause most browsers to show a popup to enter credentials on unauthorized responses. You can set the realm (the realm identifies the system to authenticate against and can be used by clients to save credentials) of the challenge by passing a static string or a function that gets passed the request object and is expected to return the challenge:
app.use(basicAuth({
users: { 'someuser': 'somepassword' },
challenge: true,
realm: 'Imb4T3st4pp',
}))
Try it
The repository contains an example.js
that you can run to play around and try the middleware. To use it just put it somewhere (or leave it where it is), run
npm install express express-basic-auth
node example.js
This will start a small express server listening at port 8080. Just look at the file, try out the requests and play around with the options.
TypeScript usage
A declaration file is bundled with the library. You don't have to install a @types/
package.
import * as basicAuth from 'express-basic-auth'
:bulb: Using req.auth
express-basic-auth sets req.auth
to an object containing the authorized credentials like { user: 'admin', password: 'supersecret' }
.
In order to use that req.auth
property in TypeScript without an unknown property error, use covariance to downcast the request type:
app.use(basicAuth(options), (req: basicAuth.IBasicAuthedRequest, res, next) => {
res.end(`Welcome ${req.auth.user} (your password is ${req.auth.password})`)
next()
})
:bulb: A note about type inference on synchronous authorizers
Due to some TypeScript's type-system limitation, the arguments' type of the synchronous authorizers are not inferred. For example, on an asynchronous authorizer, the three arguments are correctly inferred:
basicAuth({
authorizeAsync: true,
authorizer: (user, password, authorize) => authorize(null, password == 'secret'),
})
However, on a synchronous authorizer, you'll have to type the arguments yourself:
basicAuth({
authorizer: (user: string, password: string) => (password == 'secret')
})
Tests
The cases in the example.js
are also used for automated testing. So if you want
to contribute or just make sure that the package still works, simply run:
npm test