@gyeonghokim/ky-digest-auth

中文文档
1.0.0发布于 2026/11/01MITTypeScriptES Module构建来源已验证

HTTP Digest Authentication for Ky. Built for CCTV, NVR, and other embedded devices.

原始使用文档
文档目录20 节
  1. Install
  2. Usage
  3. Browser login dialog
  4. API
  5. digestAuth(options)
  6. Options
  7. Examples
  8. Typed JSON response
  9. Create a reusable client
  10. Send JSON
  11. Extend an existing Ky instance
  12. Combine with other hooks
  13. Retry behavior
  14. CORS
  15. Security
  16. Supported environments
  17. Hashing
  18. Supported authentication
  19. Development
  20. License

@gyeonghokim/ky-digest-auth

npm version CI license

HTTP Digest Authentication for Ky.

Install

npm install ky @gyeonghokim/ky-digest-auth

Usage

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);

The plugin automatically:

  1. Receives the 401 Unauthorized response.
  2. Parses the WWW-Authenticate: Digest challenge.
  3. Calculates the Digest authorization response.
  4. Retries the request with the generated Authorization header.

Browser login dialog

When a page calls a Digest-protected API on its own origin, browsers intercept the 401 and show their native login dialog, holding the request until the user submits it. The response never reaches Ky's hooks.

To prevent this, the plugin sends every request with credentials: 'omit'. This overrides any credentials option you pass, and it only turns off browser-managed credentials: cookies are neither sent nor stored for these requests, and cached HTTP auth and client certificates are not used. The Authorization header computed by the plugin is still sent. Cross-origin requests with Ky's default credentials behave exactly as before.

API

digestAuth(options)

Returns a Ky hooks configuration that handles HTTP Digest Authentication.

import ky from 'ky';
import { digestAuth } from '@gyeonghokim/ky-digest-auth';

const api = ky.create({
  hooks: digestAuth({
    username: 'admin',
    password: 'password',
  }),
});

Options

username

Type: string

The username used for Digest Authentication.

password

Type: string

The password used for Digest Authentication.

algorithms

Type:

Array<'MD5' | 'MD5-sess' | 'SHA-256' | 'SHA-256-sess' | 'SHA-512-256' | 'SHA-512-256-sess'>;

Optional list of allowed Digest algorithms.

const api = ky.create({
  hooks: digestAuth({
    username: 'admin',
    password: 'password',
    algorithms: ['SHA-256', 'MD5'],
  }),
});

When omitted, all algorithms supported by this package are allowed.

Many embedded devices (CCTV, NVR, and similar systems) still issue MD5 challenges. Because the Web Crypto API does not implement MD5 or SHA-512-256, this package computes every Digest hash with @noble/hashes, an audited, zero-dependency, tree-shakeable hashing library. All listed algorithms work in any supported runtime without extra configuration. See Supported environments for details.

preemptive

Type: boolean Default: false

Reuses a previously received Digest challenge for later requests to the same protection space.

const api = ky.create({
  hooks: digestAuth({
    username: 'admin',
    password: 'password',
    preemptive: true,
  }),
});

The first request still requires a server challenge.

cnonce

Type: () => string

Overrides the client nonce generator.

const api = ky.create({
  hooks: digestAuth({
    username: 'admin',
    password: 'password',
    cnonce: () => 'custom-client-nonce',
  }),
});

This is mainly useful for deterministic tests. The default implementation uses a cryptographically secure random value.

Examples

Typed JSON response

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);

Create a reusable client

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();

Send JSON

await deviceApi.put('configuration', {
  json: {
    enabled: true,
    quality: 'high',
  },
});

Extend an existing Ky instance

const baseApi = ky.create({
  timeout: 10_000,
  headers: {
    Accept: 'application/json',
  },
});

const deviceApi = baseApi.extend({
  hooks: digestAuth({
    username: 'admin',
    password: 'password',
  }),
});

Combine with other hooks

Ky hook arrays must be merged when multiple integrations use the same lifecycle hook.

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 ?? []),
    ],
  },
});

Retry behavior

Digest Authentication requires at least one additional request after receiving the initial challenge.

The plugin uses Ky's afterResponse hook and forced retry mechanism to retry the request with the generated Authorization header.

Do not disable retries completely:

const api = ky.create({
  retry: {
    limit: 1,
  },
  hooks: digestAuth({
    username: 'admin',
    password: 'password',
  }),
});

The following configuration prevents Digest Authentication from completing:

const api = ky.create({
  retry: {
    limit: 0,
  },
  hooks: digestAuth({
    username: 'admin',
    password: 'password',
  }),
});

The plugin prevents an authentication challenge from causing an infinite retry loop.

CORS

HTTP Digest Authentication does not bypass the browser's same-origin policy.

For a cross-origin request, the server must expose the WWW-Authenticate response header:

Access-Control-Expose-Headers: WWW-Authenticate

It must also allow the Authorization request header:

Access-Control-Allow-Headers: Authorization, Content-Type

A typical CORS response may include:

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

Many embedded devices do not provide a complete CORS implementation. When the target server does not support the required CORS headers, use a same-origin backend or reverse proxy.

Browser
   |
   | Application authentication
   v
Backend or reverse proxy
   |
   | Digest Authentication
   v
Device or legacy service

Security

Do not embed shared service credentials in publicly distributed browser code.

Credentials used by browser JavaScript can be inspected by the current user. Browser-side Digest Authentication is appropriate when:

  • the user provides their own credentials;
  • the user is permitted to access those credentials; or
  • the application runs in a controlled environment with an appropriate threat model.

Use a trusted backend for fixed or privileged service credentials.

Digest Authentication does not encrypt HTTP traffic. Use HTTPS whenever the target server supports it.

Supported environments

The package requires a Fetch-compatible runtime with:

  • fetch
  • Request
  • Response
  • Headers
  • crypto.getRandomValues (for the default client nonce)

Node.js >= 26 is required when running outside the browser.

It is intended for modern browsers and other runtimes supported by Ky.

Hashing

The Web Crypto API only exposes SHA-1, SHA-256, SHA-384, and SHA-512. It does not provide MD5 or SHA-512-256, both of which are common in the Digest challenges issued by CCTV, NVR, and other embedded devices. (SHA-512-256 is a distinct algorithm from SHA-512, using different initial values rather than a simple truncation, so a native SHA-512 digest cannot be reused for it.)

Rather than relying on Web Crypto for hashing, the package computes every algorithm through @noble/hashes:

AlgorithmModule
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 is an audited, zero-dependency, tree-shakeable library, so only the algorithms you actually use are included in your bundle, and every listed algorithm works in any Fetch-compatible runtime out of the box. It is installed automatically as a dependency of this package.

Supported authentication

This package handles HTTP Digest Authentication.

It does not provide:

  • Basic Authentication
  • Bearer tokens
  • OAuth
  • NTLM
  • Negotiate or Kerberos
  • form-based authentication
  • cookie-based session management

Development

npm install
npx playwright install chromium # once, for the browser tests
npm test

npm test runs the Node tests and the Chromium browser tests, including a check that same-origin Digest requests never trigger the browser login dialog.

License

MIT

版本与发布记录

@gyeonghokim/ky-digest-auth 共发布 3 个版本,首次发布于 2026/07/13;过去 12 个月发布了 3 个版本。最新版本附带 npm provenance 构建来源证明,可追溯到公开的 CI 构建记录。

版本发布日期距今
1.0.0latest2026/11/012 天前
0.1.02026/07/133 个月前
0.0.02026/07/133 个月前

关于 @gyeonghokim/ky-digest-auth 的常见问题

@gyeonghokim/ky-digest-auth 是什么?

key的HTTP摘要身份验证。为CCTV, NVR和其他嵌入式设备而构建。

如何安装 @gyeonghokim/ky-digest-auth?

在项目目录运行 npm install @gyeonghokim/ky-digest-auth,或使用 pnpm add / yarn add / bun add。它还需要宿主项目提供 peer 依赖:ky(>=2.0.0)。npm 7 及以上与 pnpm 8 及以上默认会自动安装必需的 peer 依赖,Yarn 需要手动安装。

@gyeonghokim/ky-digest-auth 支持 TypeScript 吗?

支持。包内自带 TypeScript 类型声明(package.json 声明了 types 入口),安装后即可获得类型提示,无需再安装 @types 包。

@gyeonghokim/ky-digest-auth 支持 ESM 还是 CommonJS?

以 ES Module 形式发布,推荐使用 import 引入。在 CommonJS 项目中,Node.js 20.19+ / 22.12+ 可以直接 require() 不含顶层 await 的 ES Module,更早的版本需要改用动态 import()。

@gyeonghokim/ky-digest-auth 需要什么版本的 Node.js?

package.json 的 engines 字段要求 Node.js >=26。版本不符时 npm 默认只给出警告,开启 engine-strict 后会拒绝安装。

@gyeonghokim/ky-digest-auth 可以商用吗?

@gyeonghokim/ky-digest-auth 使用 MIT 许可。宽松许可:允许商业使用、修改和再分发,通常只需在分发时保留原版权与许可声明。以上为概括,不构成法律意见,请以许可原文为准。

@gyeonghokim/ky-digest-auth 还在维护吗?

最新版本 1.0.0 发布于 2026/11/01(2 天前);至今共发布 3 个版本,其中过去 12 个月发布了 3 个;首次发布于 2026/07/13。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。