@gyeonghokim / ky-digest-auth
HTTP摘要身份验证 肯塔基州.
安装
npm install ky @gyeonghokim/ky-digest-auth
使用
import ky from 'ky';
import { digestAuth } from '@gyeonghokim/ky-digest-auth';
const api = ky.create({
hooks: digestAuth({
username: 'admin',
password: 'password',
}),
});
const data = await api.get('https://device.example.com/api/status').json();
console.log(data);
插件自动:
- 接收
401 Unauthorized响应。 - 解析
WWW-Authenticate: Digest挑战。 - 计算摘要授权响应。
- 重新尝试使用生成的
Authorization头。
浏览器登录对话框
调用受摘要保护的API时 自己的起源,浏览器
拦截 401 并显示其本地登录对话框,保存请求
直到用户提交。这种回应从来没有打动过Ky。
为了防止这种情况,插件发送每个请求 credentials: 'omit'.
这将覆盖任何 credentials 你通过了这个选项,它就会关闭
浏览器管理的凭据:既不发送也不存储这些凭据的cookie
请求、缓存的HTTP身份验证和客户端证书不被使用。这个
Authorization 由插件计算的头仍然被发送。跨源
使用Ky的默认凭据的请求与以前完全一样。
API
digestAuth(options)
返回处理HTTP摘要身份验证的Ky hooks配置。
import ky from 'ky';
import { digestAuth } from '@gyeonghokim/ky-digest-auth';
const api = ky.create({
hooks: digestAuth({
username: 'admin',
password: 'password',
}),
});
选项
username
类型: string
用于摘要身份验证的用户名。
password
类型: string
用于摘要身份验证的密码。
algorithms
类型:
Array<'MD5' | 'MD5-sess' | 'SHA-256' | 'SHA-256-sess' | 'SHA-512-256' | 'SHA-512-256-sess'>;
允许的摘要算法的可选列表。
const api = ky.create({
hooks: digestAuth({
username: 'admin',
password: 'password',
algorithms: ['SHA-256', 'MD5'],
}),
});
如果省略,则允许此包支持的所有算法。
许多嵌入式设备(CCTV、NVR和类似的系统)仍然存在问题 MD5
挑战。因为Web加密API没有实现 MD5 或者
SHA-512-256,此包计算每个Digest散列值
@noble/hashes,经审计的;
零依赖,可摇树哈希库。所有列出的算法都在
任何支持的运行时,无需额外配置。看到
支持环境 获取详细信息。
preemptive
类型: boolean
默认值: false
重用以前接收到的Digest挑战,以应对对同一保护空间的后续请求。
const api = ky.create({
hooks: digestAuth({
username: 'admin',
password: 'password',
preemptive: true,
}),
});
第一个请求仍然需要服务器挑战。
cnonce
类型: () => string
覆盖客户端随机数生成器。
const api = ky.create({
hooks: digestAuth({
username: 'admin',
password: 'password',
cnonce: () => 'custom-client-nonce',
}),
});
这主要用于确定性测试。默认实现使用加密安全的随机值。
示例
类型化JSON响应
import ky from 'ky';
import { digestAuth } from '@gyeonghokim/ky-digest-auth';
type DeviceStatus = {
online: boolean;
firmwareVersion: string;
};
const api = ky.create({
hooks: digestAuth({
username: 'admin',
password: 'password',
}),
});
const status = await api.get('https://device.example.com/api/status').json<DeviceStatus>();
console.log(status.firmwareVersion);
创建一个可重用的客户机
const deviceApi = ky.create({
baseUrl: 'https://device.example.com/api/',
hooks: digestAuth({
username: 'admin',
password: 'password',
}),
});
const status = await deviceApi.get('status').json();
const configuration = await deviceApi.get('configuration').json();
发送JSON
await deviceApi.put('configuration', {
json: {
enabled: true,
quality: 'high',
},
});
扩展现有的Ky实例
const baseApi = ky.create({
timeout: 10_000,
headers: {
Accept: 'application/json',
},
});
const deviceApi = baseApi.extend({
hooks: digestAuth({
username: 'admin',
password: 'password',
}),
});
与其他挂钩结合使用
当多个集成使用同一个生命周期钩子时,必须合并Ky钩子数组。
const digestHooks = digestAuth({
username: 'admin',
password: 'password',
});
const api = ky.create({
hooks: {
beforeRequest: [
({ request }) => {
request.headers.set('X-Client-Version', '1.0.0');
},
...(digestHooks.beforeRequest ?? []),
],
afterResponse: [
({ response }) => {
console.log(response.status);
},
...(digestHooks.afterResponse ?? []),
],
},
});
重试行为
摘要身份验证在收到初始质询后至少需要一个附加请求。
该插件使用Ky's afterResponse 钩子和强制重试机制,用生成的请求重试 Authorization 头。
不要完全禁用重试:
const api = ky.create({
retry: {
limit: 1,
},
hooks: digestAuth({
username: 'admin',
password: 'password',
}),
});
以下配置会阻止Digest Authentication完成:
const api = ky.create({
retry: {
limit: 0,
},
hooks: digestAuth({
username: 'admin',
password: 'password',
}),
});
该插件可防止身份验证挑战导致无限重试循环。
歌珥
HTTP摘要身份验证不绕过浏览器的同源策略。
对于跨域请求,服务器必须公开 WWW-Authenticate 响应头:
Access-Control-Expose-Headers: WWW-Authenticate
它还必须允许 Authorization 请求头:
Access-Control-Allow-Headers: Authorization, Content-Type
典型的CORS响应可能包括:
Access-Control-Allow-Origin: https://app.example.com
Access-Control-Allow-Methods: GET, POST, PUT, PATCH, DELETE, OPTIONS
Access-Control-Allow-Headers: Authorization, Content-Type
Access-Control-Expose-Headers: WWW-Authenticate
许多嵌入式设备不提供完整的CORS实现。当目标服务器不支持所需的CORS标头时,请使用同源后端或反向代理。
Browser
|
| Application authentication
v
Backend or reverse proxy
|
| Digest Authentication
v
Device or legacy service
安全
不要在公开分发的浏览器代码中嵌入共享服务凭据。
当前用户可以检查浏览器JavaScript使用的凭据。浏览器端摘要身份验证适用于以下情况:
- 用户提供自己的凭据;
- 允许用户访问这些凭据;或
- 应用程序在具有适当威胁模型的受控环境中运行。
为固定或特权服务凭证使用可信后端。
摘要认证不加密HTTP流量。只要目标服务器支持HTTPS,就使用它。
支持环境
该包需要一个兼容fetch的运行时:
fetchRequestResponseHeaderscrypto.getRandomValues(对于默认客户端nonce)
node . js >= 26 在浏览器外运行时需要。
它适用于现代浏览器和Ky支持的其他运行时。
哈希
Web Crypto API只公开 SHA-1, SHA-256, SHA-384, SHA-512.
它 不 提供 MD5 或者 SHA-512-256,这两种情况在美国都很常见
摘要CCTV、NVR和其他嵌入式设备所面临的挑战。(SHA-512-256
一个不同的算法是从 SHA-512,而是使用不同的初始值
比一个简单的截断,所以一个原生 SHA-512 不能为它重用Digest。)
而不是依赖于Web加密的哈希,包计算每一个
算法通过 @noble/hashes:
| 算法 | 模块 |
|---|---|
MD5, MD5-sess | @noble/hashes/legacy.js |
SHA-256, SHA-256-sess | @noble/hashes/sha2.js |
SHA-512-256, SHA-512-256-sess | @noble/hashes/sha2.js |
@noble/hashes 是一个审计的、零依赖的、可摇树的库吗
您实际使用的算法包含在您的包中,并且每个都列出了
算法可以在任何与fetch兼容的开箱即用运行时中工作。已经安装好了
自动作为此包的依赖项。
支持身份验证
这个包处理HTTP摘要身份验证。
它没有规定:
- 基本身份验证
- 不记名的令牌
- OAuth
- NTLM
- 协商还是Kerberos
- 基于表单的认证
- 基于cookie的会话管理
开发
npm install
npx playwright install chromium # once, for the browser tests
npm test
npm test 运行Node测试和Chromium浏览器测试,包括
检查同源摘要请求永远不会触发浏览器登录
对话框。
许可证
麻省理工学院