网络安全认证鉴权后端【免费下载链接】joseJWA, JWS, JWE, JWT, JWK, JWKS for Node.js, Browser, Cloudflare Workers, Deno, Bun, and other Web-interoperable runtimes项目地址https://gitcode.com/gh_mirrors/jo/jose点击查看免费下载本文围绕 jose 库中createRemoteJWKSet返回的密钥解析函数RemoteJWKSet系统讲解其函数签名、实例属性、内置的缓存与冷却cooldown机制以及jwksCache、customFetch、RemoteJWKSetOptions等配套选项的完整用法。读者读完将掌握如何在 Node.js、浏览器、Cloudflare Workers、Deno、Bun 等 Web-interoperable 运行时中基于 OAuth 2.0 / OIDC 的jwks_uri端点实现 JWT 验签的自动密钥发现、缓存刷新与错误处理并能结合源码理解其底层实现。一、RemoteJWKSet 是什么RemoteJWKSet是调用createRemoteJWKSet后返回的一个可调用对象callable它本身是一个异步函数用于把 JWS JOSE Header 解析resolve为用于验签的公钥对象同时对象身上还挂载了若干描述其内部缓存状态的只读属性与方法。完整定义见 src/jwks/remote.ts 与 接口文档。它可以直接传给jwtVerify以及所有接受密钥解析函数的消费方如compactVerify、flattenedVerify、generalVerify等相关说明见 jwtVerify 文档。也就是说你几乎不需要直接调用RemoteJWKSet本身——把它作为getKey参数传给验签 API 即可。函数签名▸ RemoteJWKSet( protectedHeader?: JWSHeaderParameters, token?: FlattenedJWSInput, ): PromiseCryptoKey参数类型说明protectedHeader?JWSHeaderParametersJWS 受保护头包含alg、kid等用于选键的参数token?FlattenedJWSInput扁平化 JWS 输入含protected、payload、signature等字段返回值PromiseCryptoKey即解析得到的 Web Crypto API 公钥对象。[!NOTE] 该函数的用途是解析验签用公钥不会用于公钥加密场景。二、实例属性与方法详解RemoteJWKSet除了可调用之外还通过Object.defineProperties安装了五个实例成员实现见 src/jwks/remote.ts用于观测和控制内部的 JWKS 缓存状态。成员类型语义coolingDownreadonly boolean自上次成功 fetch 之后冷却窗口是否仍在生效即是否处于冷却期内freshreadonly boolean当前缓存的 JWKS 是否仍在其 cacheMaxAge 有效期之内reloadingreadonly boolean是否正有一个 JWKS fetch 请求在途in flightreload()() Promisevoid主动触发一次 JWKS fetch绕过冷却期jwks()() JSONWebKeySet \| undefined返回当前缓存的JSONWebKeySet尚未 fetch 或未通过jwksCache播种时返回undefined三个布尔状态的生命周期从 test/jwks/remote.test.ts 的createRemoteJWKSet manual reload测试可以清楚看到各状态的流转创建之初尚未发生任何 fetchcoolingDown false、fresh false、reloading false且jwks()返回undefined首次 fetch 成功后coolingDown与fresh立即变为truefresh取决于cacheMaxAgecoolingDown取决于cooldownDuration调用reload()期间reloading truefetch 完成后回到false手动修改jwks()返回值无效测试中JWKS.jwks()!.keys []之后再验签依然成功说明该函数返回的是内部不可变的快照/代理视图直接改返回对象不会污染内部缓存。reload() 的语义reload()是唯一主动刷新手段它绕过cooldownDuration的冷却限制强制拉取一次 JWKS。结合jwksCache使用时成功 fetch 的结果也会同步写回外部缓存对象见下文。三、缓存与节流RemoteJWKSet 的底层行为要正确使用RemoteJWKSet必须理解其背后的两级缓存策略实现见 src/jwks/remote.ts首次解析或缓存过期时若本地没有缓存或缓存已超过cacheMaxAge先触发一次 fetch本地解析失败时若JWKSNoMatchingKey无匹配密钥抛出且距离上次成功 fetch 已超过cooldownDuration则再次 fetch 并重试一次解析——这是为了让远端轮换密钥后本地缓存能在冷却结束后尽快自动更新冷却期内不会因为“无匹配密钥”而反复打爆远端端点这是防止滥用abuse的核心设计。整个 fetch 过程由内部fetchJwks完成src/jwks/remote.ts它要求 HTTP 响应必须是200并将响应体解析为 JSON超时或解析失败分别抛出JWKSTimeout与JOSEError。并发与序列保护源码通过reloadSequence/appliedSequence两个递增计数器确保较旧的 fetch 结果不会覆盖较新的结果见 src/jwks/remote.ts 与 test/jwks/remote.test.ts 的 workerd 并发测试同时在 Cloudflare Workers 等隔离型运行时中若存在上一个请求遗留的 in-flight fetch会被主动作废pendingFetch undefined见 src/jwks/remote.ts避免旧请求的 Promise 干扰新请求。选键规则选键严格遵循 RFC 语义先用 Header 的alg决定 JWK 的kty再用kid匹配 JWK 的kid若 Header 中存在同时尊重 JWK 上的use如sig与key_ops。必须恰好匹配到一个公钥匹配不到抛JWKSNoMatchingKey匹配到多个抛JWKSMultipleMatchingKeys该错误可迭代见 src/util/errors.ts。四、快速上手创建并使用 RemoteJWKSetconst JWKS jose.createRemoteJWKSet(new URL(https://www.googleapis.com/oauth2/v3/certs)) const { payload, protectedHeader } await jose.jwtVerify(jwt, JWKS, { issuer: urn:example:issuer, audience: urn:example:audience, }) console.log(protectedHeader) console.log(payload)这是 官方示例 中的标准用法createRemoteJWKSet只接收URL与可选的RemoteJWKSetOptions返回的JWKS函数直接充当jwtVerify的密钥解析器。jwtVerify内部会依次调用RemoteJWKSet(protectedHeader, token)来解析公钥见 src/jwt/verify.ts 的消费方式。导入方式该能力从主入口jose以及子路径jose/jwks/remote均有命名导出相关导出见 src/index.tsimport { createRemoteJWKSet, jwksCache, customFetch } from jose // 或 import { createRemoteJWKSet, jwksCache, customFetch } from jose/jwks/remote五、RemoteJWKSetOptions全部可配置项创建RemoteJWKSet时可传入以下选项完整说明见 RemoteJWKSetOptions 文档默认值与校验逻辑见 src/jwks/remote.ts 与validateDurationsrc/jwks/remote.ts选项类型默认值说明timeoutDurationnumber50005 秒HTTP 请求超时时间毫秒。超时后请求被中止、验签失败。必须是非负整数cooldownDurationnumber3000030 秒上次成功 fetch 后的一段时间毫秒内不再触发新的 HTTP 请求防止滥用。不能为NaNcacheMaxAgenumber60000010 分钟两次成功 HTTP 请求之间的最大间隔毫秒即缓存有效期。不能为NaN源码类型上还允许InfinityheadersRecordstring, string—随 HTTP 请求发送的额外请求头[jwksCache]JWKSCacheInput—外部可写缓存对象见下文[customFetch]FetchImplementation全局fetch自定义 fetch 实现关于默认请求头创建解析器时源码会为请求设置默认请求头src/jwks/remote.tsUser-Agentjose/v6.2.10浏览器环境为避免触发不必要的 CORS preflight 而省略acceptapplication/json, application/jwk-setjson若你未自定义。test/jwks/remote.test.ts中对user-agent头做了断言test/jwks/remote.test.ts说明该默认值是可观测的。六、jwksCache面向无状态云运行时的持久缓存jwksCache是一个unique symbolsrc/jwks/remote.ts专为无法在两次调用之间保留内存缓存的云函数/边缘运行时设计如某些 Serverless 与 Workers 环境。[!WARNING] 该选项存在安全影响必须保证 JWKS 缓存对象只能被你自己的代码写入否则可能被注入恶意公钥。传入jwksCache后你提供的可写对象承担两个职责见 jwksCache 文档作为初始缓存如果对象携带合法的jwks与uat且uat仍在cacheMaxAge内解析器会直接用它构建本地选键器免去首次 HTTP 请求作为回写目标成功 fetch 后解析器会把新的jwks与uat写回该对象。缓存对象的结构为ExportedJWKSCache{ jwks: JSONWebKeySet; uat: number }其中uat是“最后更新时间”毫秒时间戳。输入类型JWKSCacheInput允许ExportedJWKSCache或空对象{}类型别名。推荐使用模式// 前提从低延迟 KV 存储拉取上次缓存 let getPreviouslyCachedJWKS!: () Promisejose.ExportedJWKSCache let storeNewJWKScache!: (cache: jose.ExportedJWKSCache) Promisevoid const jwksCache: jose.JWKSCacheInput (await getPreviouslyCachedJWKS()) || {} const { uat } jwksCache const JWKS jose.createRemoteJWKSet(url, { [jose.jwksCache]: jwksCache, }) await jose.jwtVerify(jwt, JWKS) if (uat ! jwksCache.uat) { await storeNewJWKScache(jwksCache) }核心逻辑验签前先取缓存无则{}验签后对比uat是否变化变化才回写存储。这避免了每次冷启动都重新拉取 JWKS也避免了在每次调用中把整份 JWKS 打进存储。源码中的回写发生在reload内部src/jwks/remote.ts。七、customFetch自定义 fetch 实现customFetch同样是unique symbolsrc/jwks/remote.ts用于把解析器内部的 HTTP 请求替换成你自己的实现从而获得代理、重试、日志、测试 mock 等能力。其类型FetchImplementation的签名为type FetchImplementation ( url: string, options: { headers: Headers method: GET redirect: manual signal: AbortSignal }, ) PromiseResponse[!NOTE] 已知坑把options透传给 ky 等 fetch 类库时大概率遇到类型不匹配这些库的 typings 几乎不与原生 fetch 完全对齐建议使用ts-expect-error处理。用 ky 实现重试与日志import ky from ky const JWKS jose.createRemoteJWKSet(url, { [jose.customFetch]: (...args) ky(args[0], { ...args[1], hooks: { beforeRequest: [(request) { logRequest(request) }], beforeRetry: [({ request, error, retryCount }) { logRetry(request, error, retryCount) }], afterResponse: [(request, _, response) { logResponse(request, response) }], }, }), })用 undici 接入 HTTP 代理import * as undici from undici let envHttpProxyAgent new undici.EnvHttpProxyAgent() const JWKS jose.createRemoteJWKSet(url, { [jose.customFetch]: (...args) // ts-ignore undici.fetch(args[0], { ...args[1], dispatcher: envHttpProxyAgent }), })用 undici 自动重试网络错误import * as undici from undici let retryAgent new undici.RetryAgent(new undici.Agent(), { statusCodes: [], errorCodes: [ ECONNRESET, ECONNREFUSED, ENOTFOUND, ENETDOWN, ENETUNREACH, EHOSTDOWN, UND_ERR_SOCKET, ], }) const JWKS jose.createRemoteJWKSet(url, { [jose.customFetch]: (...args) // ts-ignore undici.fetch(args[0], { ...args[1], dispatcher: retryAgent }), })用 undici MockAgent 在测试中模拟响应import * as undici from undici let mockAgent new undici.MockAgent() mockAgent.disableNetConnect() const JWKS jose.createRemoteJWKSet(url, { [jose.customFetch]: (...args) // ts-ignore undici.fetch(args[0], { ...args[1], dispatcher: mockAgent }), })这一模式正是 test/jwks/remote.test.ts 所采用的测试策略整个测试套件通过 MockAgent 拦截https://as.example.com/jwks的响应并用timekeeper冻结/拨快时间轴来验证冷却与过期行为。八、错误处理与多密钥迭代远程 JWKS 场景最常见的错误集中在 src/util/errors.ts 中定义均可通过jose.errors访问错误类code触发条件JWKSNoMatchingKeyERR_JWKS_NO_MATCHING_KEYJWKS 中没有任何可用密钥匹配选键条件JWKSMultipleMatchingKeysERR_JWKS_MULTIPLE_MATCHING_KEYS有多个密钥同时匹配可迭代以逐个尝试验签JWKSTimeoutERR_JWKS_TIMEOUTfetch 超时对应timeoutDuration多密钥匹配时的迭代验签默认策略是“恰好一个匹配”若远端 JWKS 中存在多个满足条件的公钥例如两把 RSA 密钥都未声明algjwtVerify会抛JWKSMultipleMatchingKeys。此时可以显式迭代该错误逐一尝试验签const options { issuer: urn:example:issuer, audience: urn:example:audience, } const { payload, protectedHeader } await jose .jwtVerify(jwt, JWKS, options) .catch(async (error) { if (error instanceof jose.errors.JWKSMultipleMatchingKeys) { for await (const publicKey of error) { try { return await jose.jwtVerify(jwt, publicKey, options) } catch (innerError) { if (innerError instanceof jose.errors.JWSSignatureVerificationFailed) { continue } throw innerError } } throw new jose.errors.JWSSignatureVerificationFailed() } throw error }) console.log(protectedHeader) console.log(payload)这里error本身是异步可迭代的async iterable每次产出的是一个public类型的CryptoKey只有JWSSignatureVerificationFailed会被吞掉继续尝试下一个密钥其余错误直接向上抛出。测试 test/jwks/remote.test.ts 验证了这一迭代行为并确认两次迭代产生的密钥对象是同一个内部有 WeakSet 缓存。九、实现要点小结RemoteJWKSet 可调用函数 5 个实例成员coolingDown、fresh、reloading、reload、jwks全部由createRemoteJWKSet在 src/jwks/remote.ts 中安装两级节流cacheMaxAge10 分钟默认控制缓存新鲜度cooldownDuration30 秒默认控制失败重试时的 fetch 频率timeoutDuration5 秒默认控制单次请求上限无状态运行时用jwksCache做外部持久缓存验签前后比对uat决定是否回写高级网络需求代理、重试、日志、mock通过customFetch以 symbol 选项注入实测行为与上述语义完全对应见 test/jwks/remote.test.ts。赞分享网络安全认证鉴权后端【免费下载链接】joseJWA, JWS, JWE, JWT, JWK, JWKS for Node.js, Browser, Cloudflare Workers, Deno, Bun, and other Web-interoperable runtimes项目地址https://gitcode.com/gh_mirrors/jo/jose点击查看免费下载相关推荐jose 本地 JWKS 公钥解析createLocalJWKSet 完全指南jose 本地 JWKS 公钥解析createLocalJWKSet 完全指南 本篇技术指南围绕 jose 库的 createLocalJWKSet 展开讲网络安全认证鉴权后端jose 通用 JWS 验证动态密钥解析GeneralVerifyGetKey 接口全解析jose 通用 JWS 验证动态密钥解析GeneralVerifyGetKey 接口全解析 通用 JSON 序列化General JSON Serializ网络安全认证鉴权后端scalar/highlight 源码级解析Scalar 零依赖高性能语法高亮引擎与 40 种语言语法体系scalar/highlight 源码级解析Scalar 零依赖高性能语法高亮引擎与 40 种语言语法体系 本篇技术指南围绕 Scalar 开源仓库中的代码网络安全认证鉴权后端上一篇5分钟掌握AMD锐龙SMU调试工具释放处理器隐藏性能的完整方案下一篇如何掌握AMD锐龙SDT调试工具从入门到精通的完整指南创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
企业数字化 ERP 产品动态
相关推荐
NodeMCU 固件 APA102 模块实战指南:用 Lua 驱动 DotStar RGB LED 灯带 物联网嵌入式 【免费下载链接】nodemcu-firmware Lua based interactive firmware for ESP8266, ESP8285 and ESP32 项目地址: https://gitcode.com/gh_mirrors/no/nodemcu-firmware 点击查看 免费下载 导读
本指南基于 nodemcu-firmware 仓库中的 APA102 模块文档… · 2026/9/27 10:50:59
提高网站权重避坑指南:技术栈怎么选才不白干 提高网站权重避坑指南:技术栈怎么选才不白干 别再说“网站做好了就行”,现在的甲方一开口就是:“这模板太丑,权重还上不去。” 模板网站太丑不够用 ,更致命的是,底层架构烂,搜索引擎爬虫都进不去,你优化得再好也是白搭。 很多老板以为… · 2026/9/27 10:50:59
好书分享《父与子的编程之旅:与小卡特一起学Python》 本书是面向家长与孩子的亲子编程入门书籍,作者为一对父子。书中选用 Python 语言,细致讲解 Python 的安装方式、字符串、运算符等基础编程知识,还介绍了条件语句、函数、模块等进阶内容,最后演示如何利用 Python 进行游戏编程。全… · 2026/9/27 10:50:59
智能模型路由(AI Router)实战:用虚拟模型统一调度多模型 API,告别手动切换 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/27 18:36:36
mac 笔记本上 UltraEdit 与终端工具配置 TaoToken 的完整方法 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/27 18:36:30
OpenClaw 对话文本生成幻觉抑制:TaoToken 统一 API 通道下的配置与验证 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/27 18:36:24
CodeGraph为什么突然这么火?用TaoToken统一Key跑通代码图谱构建全流程 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/27 18:36:24
MATLAB雷达信号脉冲压缩仿真:LFM线性调频、匹配滤波与距离分辨率实现 简介:这套Matlab仿真工具完整呈现雷达信号脉冲压缩过程,从线性调频(LFM)信号生成、目标回波仿真到匹配滤波压缩处理均有可运行代码支撑,面向电子信息工程、计算机、数学等专业学生,适用于课程设计、期末大作… · 2026/9/27 0:00:01
汕头网站建设制作厂家避坑指南:5大注意事项救急 汕头网站建设制作厂家避坑指南:5大注意事项救急 改个需求建站公司拖一周,这种憋屈事我见得太多了。 很多汕头老板找本地建站团队,签合同前看着方案挺美,一上线就变脸。 今天不聊虚的,直接拆解找 汕头网站建设制作厂家 时的5个核心 注意事项… · 2026/9/27 0:00:01
多模态虚假新闻检测实战:BERT+ResNet双塔与对比学习 简介:基于PyTorch的多模态虚假新闻检测项目完整代码包,面向自然语言处理与计算机视觉交叉方向的开发者、科研人员及毕业设计选题者,解决社交媒体中文本与图像联合识别虚假新闻的问题。系统以BERT预训练模型提取文本语义特征,以Res… · 2026/9/27 0:00:01
MATLAB雷达信号脉冲压缩仿真:LFM线性调频、匹配滤波与距离分辨率实现 简介:这套Matlab仿真工具完整呈现雷达信号脉冲压缩过程,从线性调频(LFM)信号生成、目标回波仿真到匹配滤波压缩处理均有可运行代码支撑,面向电子信息工程、计算机、数学等专业学生,适用于课程设计、期末大作… · 2026/9/27 0:00:01
汕头网站建设制作厂家避坑指南:5大注意事项救急 汕头网站建设制作厂家避坑指南:5大注意事项救急 改个需求建站公司拖一周,这种憋屈事我见得太多了。 很多汕头老板找本地建站团队,签合同前看着方案挺美,一上线就变脸。 今天不聊虚的,直接拆解找 汕头网站建设制作厂家 时的5个核心 注意事项… · 2026/9/27 0:00:01
多模态虚假新闻检测实战:BERT+ResNet双塔与对比学习 简介:基于PyTorch的多模态虚假新闻检测项目完整代码包,面向自然语言处理与计算机视觉交叉方向的开发者、科研人员及毕业设计选题者,解决社交媒体中文本与图像联合识别虚假新闻的问题。系统以BERT预训练模型提取文本语义特征,以Res… · 2026/9/27 0:00:01