# @effected/jwt 中文文档

规范地址：https://npmcn.com/package/%40effected/jwt/

版本：0\.10\.0
npm 元数据更新时间：2026-11-10T15:09:22.870Z
中文译文更新时间：2026-11-13T08:49:50.984Z
软件包许可：MIT

本文由上游 README 翻译，可能存在偏差，请结合原文核对 API、命令与配置。版权与许可归原作者所有。

原始 npm 页面：https://www.npmjs.com/package/%40effected/jwt
原文对照：https://npmcn.com/package/%40effected/jwt/?lang=original
项目主页：https://github.com/spencerbeggs/effected/tree/main/packages/jwt#readme
源码仓库：https://github.com/spencerbeggs/effected

## 关键信息（来自 npm 元数据）

- 包体积（解压后）：91.5 kB，21 个文件
- 模块格式：ES Module
- TypeScript 类型：包内自带
- Node.js 要求：\>=24\.11\.0
- 运行依赖：1 个
- peer 依赖：effect ~4\.1\.0
- 首次发布：2026-10-10T03:02:13.682Z
- 最新版本发布：2026-11-10T15:09:22.515Z
- 近 30 天下载量：10200（2026-10-13 至 2026-11-11，npm 官方下载统计）
- 已发布版本数：13（近 12 个月 13 个）

## 中文简介

JWS,JWT,JWK和JWKS在WebCrypto上签名并验证Effect v4,工人安全.

## 安装

```sh
npm install @effected/jwt
```

也可以使用：`pnpm add @effected/jwt`、`yarn add @effected/jwt`、`bun add @effected/jwt`

## README

# @ e受影响/ jwt

[![npm](https://img.shields.io/npm/v/@effected%2Fjwt?label=npm&color=cb3837)](https://www.npmjs.com/package/@effected/jwt) [![License: MIT](https://img.shields.io/badge/License-MIT-4caf50.svg)](https://opensource.org/licenses/MIT) [![Node.js %3E%3D24.11.0](https://img.shields.io/badge/Node.js-%3E%3D24.11.0-5fa04e.svg)](https://nodejs.org/)

签名和验证 JWTs for Effect v4,并从发行商已公布的密钥集中解析校验密钥. 一层薄的地层 `effect/jose`,它运行每个签名、密钥导入和权利要求检查,所以它在WebCrypto的任何地方都有效:Node、Bun、Deno、浏览器和Cloudflare工人,没有 `node:` 导入.

> **预`1.0.0`。 。 。 .** 此软件包是 `@effected/*` 工具箱,在 稳定效果 v4并仍在 `0.x` 发展。 为了保持你的 `effect` 财务报告和审定财务报表 `@effect/*` 该工具包在线上构建和测试、安装 [`@effected/pnpm-plugin-effected`](https://www.npmjs.com/package/@effected/pnpm-plugin-effected)。 。 。 .
> 
> **稳定:不稳定.** 此软件包的 API 表面尚未考虑 完成并可能改变 `0.x` 释放 准确的版本。 满 政策: [释放策略](https://github.com/spencerbeggs/effected#release-strategy)。 。 。 .

## 为什么 @ effect/jwt

核心 `effect/jose` 已签名并验证 JWS 和 JWT, 导入 JWK 并获取密钥集 。 当您对照您已经持有的密钥或一个固定的HTTPS JWKS URL进行校验时直接使用它(`Jwks.layerRemote`,用 PKCS#8 键签名,或需要 HMAC 或 JWE .

当您需要核心留给您时,请联系这个包:

-   **OIDC发现的钥匙.** `JwksResolver` 找到每个发行人的密钥集 `<issuer>/.well-known/openid-configuration`,检查发现文件名称 准确的发布者,服务于许多发布者 从一个服务 `kid`。 。 。 .
-   **你选择的缓存 .** 获取的密钥集以 `JwksStore`: 与 `JwksStore.layerMemory`,或者在工人KV中, 所以每一个孤立者共享一个获取.
-   **PEMs的人确实有.** `JwtKey.fromPkcs8Pem` 使用 PKCS# 8 和 PKCS# 1 ()`BEGIN RSA PRIVATE KEY`,格式 github.com 将App 键输出出去),包括一条新行到达的键作为逃出 `\n` 在一行环境变量中.
-   **更安全的违约.** `Jwt.verify` 允许 60 秒时钟 skew, 需要 `exp` 除非你们选择退出,并且拒绝将来发行的标志。 Core的默认值为零 skew 和可选 `exp`。 。 。 .
-   **一个路径错误 .** 每一次失败都是 `JwtError` 有个公寓 `reason` 绳子.
-   **试发会.** `TestIssuer` 标志通过真正的解析器进行验证,没有网络.

钥匙是核心本身的类型,所以是来自 `JwtKey` 也与核心协作 `Jws` 财务报告和审定财务报表 `Jwt` 直接说.

## 安装

```bash
npm install @effected/jwt effect
```

```bash
pnpm add @effected/jwt effect
```

在节点上,它需要Node.js QQ24.11.0;它还运行在任何其他WebCrypto运行时间上,Cloudflare Workers也包括在内. `effect` v4是唯一的对等器. 全体 `@effected/*` 软件包仅限无害环境管理.

## 提供什么

在您程序边缘提供的核心服务上签名和验证运行 :

| 运行 | 要求数 |
| --- | --- |
| `Jws.sign`, (中文(简体) ), `Jws.verify`, (中文(简体) ), `Jwt.sign`, (中文(简体) ), `Jwt.verify`, (中文(简体) ), `JwtKey.generate`, (中文(简体) ), `TestIssuer` | `Signature.Signature` |
| `JwksResolver.layer`, (中文(简体) ), `JwksResolver.layerWith` | `HttpClient.HttpClient` 财务报告和审定财务报表 `JwksStore` |
| `Jwt.verify` 键 `JwksResolver.forIssuer` | `Signature.Signature` 财务报告和审定财务报表 `JwksResolver` |

`JwtKey.fromPkcs8Pem`, (中文(简体) ), `JwtKey.fromJwk` 财务报告和审定财务报表 `Jws.decodeUnverified` 不需要任何东西.

| 服务 | 任何 WebCrypto 运行时间( 包括工人) | 节点 |
| --- | --- | --- |
| `Signature.Signature` | `Signature.layerWebCrypto.pipe(Layer.provide(SecureRandom.layerWebCrypto))` 从 `effect/crypto` | `NodeCrypto.layerSignature` 从 `@effect/platform-node` |
| `HttpClient.HttpClient` | `FetchHttpClient.layer` 从 `effect/http` | `NodeHttpClient.layerUndici` 从 `@effect/platform-node`,或 `FetchHttpClient.layer` |
| `JwksStore` | `JwksStore.layerMemory`,或您自己的 KV 备份层 | `JwksStore.layerMemory` |

```ts
import { JwksResolver, JwksStore } from "@effected/jwt";
import { Layer } from "effect";
import { SecureRandom, Signature } from "effect/crypto";
import { FetchHttpClient } from "effect/http";

const CryptoLive = Signature.layerWebCrypto.pipe(Layer.provide(SecureRandom.layerWebCrypto));

const JwtLive = Layer.merge(
  JwksResolver.layer.pipe(Layer.provide(Layer.merge(FetchHttpClient.layer, JwksStore.layerMemory))),
  CryptoLive,
);
```

## 签署 JWT

来自 PKCS# 1 关键 github.com 的 GitHub App JWT 问题. 标题是 `{"alg":"RS256","typ":"JWT"}`数字 : `alg` 总是来自钥匙.

```ts
import { Jwt, JwtKey } from "@effected/jwt";
import { Effect, Redacted } from "effect";

const signAppJwt = (pem: Redacted.Redacted<string>, appId: string, nowSeconds: number) =>
  Effect.gen(function* () {
    const key = yield* JwtKey.fromPkcs8Pem(pem, { alg: "RS256" });
    return yield* Jwt.sign({ iat: nowSeconds - 60, exp: nowSeconds + 540, iss: appId }, key);
  });
```

## 对照发行人公布的密钥校验

把发行人交给你 `forIssuer`,从来没有人从符号读取: 发行者决定哪些密钥是信任的。 总是通过 `audience` 对于一个共享的发行者,其一键为每个依赖方设置了标志.

```ts
import { JwksResolver, Jwt } from "@effected/jwt";
import { Schema } from "effect";

const Claims = Schema.Struct({ sub: Schema.String });

const verify = (token: string) =>
  Jwt.verify(token, {
    key: JwksResolver.forIssuer("https://issuer.example"),
    claims: Claims,
    issuer: "https://issuer.example",
    audience: "my-service",
  });
// Effect<{ readonly sub: string }, JwtError, JwksResolver | Signature>
```

检查按此顺序进行:签名,然后 `exp` 现在, `iss`, (中文(简体) ), `aud`, (中文(简体) ), `exp` 未通过, `nbf` 到达,你的 `claims` 计划,最后 `iat` 未来不会. `clockTolerance` 财务报告和审定财务报表 `requireExpiry` 调整默认值.

## 用您持有的密钥校验

`key` 是一个 `VerificationKey`,或从符号头到一的函数.

```ts
import { Jwk, Jwt, JwtKey } from "@effected/jwt";
import { Effect, Schema } from "effect";

const verifyWith = (jwk: Jwk, token: string) =>
  Effect.gen(function* () {
    const key = yield* JwtKey.fromJwk(jwk);
    return yield* Jwt.verify(token, { key, claims: Schema.Struct({ sub: Schema.String }) });
  });
```

`Jws` 在没有索赔规则的情况下是同一签字层(`Jws.sign`, (中文(简体) ), `Jws.verify`),以及 `Jws.decodeUnverified` 读取符号头和有效载荷作为同步 `Result`,用于路由 `kid` 或者说 `iss` 在选择密钥之前。 永远不要相信它回来.

## 算法

每个不对称算法核心设备: `RS256`, (中文(简体) ), `RS384`, (中文(简体) ), `RS512`, (中文(简体) ), `PS256`, (中文(简体) ), `PS384`, (中文(简体) ), `PS512`, (中文(简体) ), `ES256`, (中文(简体) ), `ES384`, (中文(简体) ), `ES512` 财务报告和审定财务报表 `EdDSA` (Ed25519) (英语). 该算法出自密钥,从不给符头,2048位以下的RSA密钥被拒绝. HMAC 被拒绝, 因为密钥集中公布的密钥绝不能作为共享密钥; 对于 HMAC 使用 Core 的密钥 `Jwk.importSecret` 带有核心 `Jwt`。 。 。 . `alg: "none"` 永远不会被接受.

## 错误

每一次失败都是 `JwtError`路径 `reason`永远不要 `message` 或者说 `detail`当核心产生故障时 `JoseError` 这是 `cause`。 。 。 .

| `reason` | 含义 |
| --- | --- |
| `malformed` | 不是紧凑的JWS:错误的片段计数,非冠基64url,一个不是JOSE头的片头, `alg: "none"` 或未知算法,a `crit` 或者说 `b64` 或不是JSON的有效载荷. |
| `unsupportedAlgorithm` | 符号或JWK命名为HMAC(或其他非不对称)算法. 未解决密钥 . |
| `algorithmMismatch` | 标志 `alg` 不是钥匙的算法,也不是JWK的算法 `alg` 与所需的不同. |
| `badSignature` | 签名不验证 . |
| `unknownKid` | 组合中没有匹配符号算法的密钥和 `kid`,或几个做. |
| `expired` | `exp` 已经过去了,超越了容忍. |
| `notYetValid` | `nbf` 未来,或 `iat` 是,超越宽容. |
| `wrongIssuer` | `iss` 缺少或没有被接受的发行人. |
| `wrongAudience` | `aud` 缺少或没有被接受的听众. |
| `claims` | 注册债权有错误的类型, `exp` 缺少,有效载荷 不是JSON物体,你的 `claims` schema拒绝了,否则钟容无效. |
| `key` | 关键材料没有导入:一个不正确或不支持的PEM,一个2048位以下的RSA密钥,一个JWK,其类型,曲线, `use` 或者说 `key_ops` 无法验证 . |
| `jwksFetch` | 无法发现或获取密钥集: 无法获取、 缓慢、 超大小、 不 `https:`,转出 `https:`,一个发现文件,指定另一个发行人,或者一个没有支持密钥的集. |

一个符号字符串不是身份:ECDSA签名是可商的,所以一个被签名的有效载荷可以有两个有效的符号字符串. 检测在核实的索赔中重放和撤销(`jti`,或 `iss` 与 `sub` 财务报告和审定财务报表 `iat`),从未在符号文本上.

## 测试

`@effected/jwt/testing` 出口 `TestIssuer`: 生成的密钥对, 用于邮票的签名符 `iss`, (中文(简体) ), `iat` 还有十分钟 `exp`,以及 `resolverLayer`真实的 `JwksResolver` 在一个记忆中 `HttpClient` 为发行人的发现文件和密钥集服务.

```ts
import { JwksResolver, Jwt } from "@effected/jwt";
import { TestIssuer } from "@effected/jwt/testing";
import { Effect, Schema } from "effect";

const program = Effect.gen(function* () {
  const issuer = yield* TestIssuer.make({ issuer: "https://issuer.test" });
  const token = yield* issuer.sign({ aud: "my-app", sub: "user-1" });
  return yield* Jwt.verify(token, {
    key: JwksResolver.forIssuer("https://issuer.test"),
    claims: Schema.Struct({ sub: Schema.String }),
    issuer: "https://issuer.test",
    audience: "my-app",
  }).pipe(Effect.provide(issuer.resolverLayer));
});
// provide CryptoLive: TestIssuer and Jwt.verify both need Signature
```

提供 `resolverLayer` 当它依赖于缓存或旋转时 整个测试一次. `TestIssuer.rotate(issuer, kid)` 在新键下添加密钥 `kid`\- 解析器最多每30秒调试一次 `TestClock` 在用新密钥验证前。 与 `@effect/vitest`,提供 `Signature` 每个测试(`layer(CryptoLive, { buildPerTest: true })`:为整个区块建造的一层 `TestClock` 整个测试.

## 许可证

[麻省理工学院](https://npmcn.com/package/%40effected/jwt/LICENSE)

## 常见问题

### @effected/jwt 是什么？

JWS,JWT,JWK和JWKS在WebCrypto上签名并验证Effect v4,工人安全\.

### 如何安装 @effected/jwt？

在项目目录运行 npm install @effected/jwt，或使用 pnpm add / yarn add / bun add。它还需要宿主项目提供 peer 依赖：effect（~4\.1\.0）。npm 7 及以上与 pnpm 8 及以上默认会自动安装必需的 peer 依赖，Yarn 需要手动安装。

### @effected/jwt 支持 TypeScript 吗？

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

### @effected/jwt 支持 ESM 还是 CommonJS？

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

### @effected/jwt 需要什么版本的 Node\.js？

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

### @effected/jwt 可以商用吗？

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

### @effected/jwt 的下载量有多少？

根据 npm 官方下载统计，@effected/jwt 在 2026/10/13 – 2026/11/11 这 30 天内被下载 10,200 次，日均约 340 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入，适合横向比较热度，不能直接等同于使用人数。

### @effected/jwt 还在维护吗？

最新版本 0\.10\.0 发布于 2026/11/10（2 天前）；至今共发布 13 个版本，其中过去 12 个月发布了 13 个；首次发布于 2026/10/10。发布频率只是参考信号：功能稳定的工具可能很少需要更新，建议结合源码仓库的 issue 和提交记录判断。

