@authup/server-adapter-kit

中文文档
1.0.0-beta.73发布于 2026/11/02Apache-2.0TypeScriptES Module近 30 天下载 3305

Verify Authup access tokens in your own API, locally against realm keys or by introspection.

原始使用文档
文档目录12 节
  1. Why @authup/server-adapter-kit?
  2. Installation
  3. Usage
  4. Verify locally
  5. Verify remotely
  6. Cache verified tokens
  7. Bound tokens
  8. Parse the Authorization header
  9. Options
  10. API
  11. Notes
  12. License

Authup logo

@authup/server-adapter-kit

Verify Authup access tokens in your own API, locally against realm keys or by introspection.
The verifier, caches and bearer parsing behind the Node, Socket.IO and Web adapters.

npm version CI License: Apache-2.0

Installation · Usage · API · Documentation


Why @authup/server-adapter-kit?

An API that trusts tokens issued by Authup has to fetch the right signing key, check the signature and expiry, reject tokens that are not access tokens, and decide how long a verified result may be reused. This package does that once, so every transport adapter (and your own code) shares the same rules.

ConcernWithout itWith it
Signing keysFetch the JWKS, pick the key, cache it, refetch on rotationThe key of the token's realm is fetched by kid and cached per realm and key for 5 minutes
PermissionsCall the introspection endpoint and parse the answerRemote mode introspects with your API's client credentials and returns the subject's permissions
Token kindA refresh token or MFA ticket signed with the same key passes a signature checkAny kind other than access_token is rejected
Repeat requestsVerify every token on every requestAn optional cache (memory or Redis) keeps results until the token expires
Bound tokensCompare cnf.x5t#S256 yourselfCertificate-bound tokens (RFC 8705) fail unless the presented thumbprint matches

For an HTTP server, a Socket.IO server or a Web Request handler, use one of the adapters on top of this package: @authup/server-adapter-node, @authup/server-adapter-socket-io or @authup/server-adapter-web.

Installation

npm install @authup/server-adapter-kit

The package is ESM-only and needs Node.js >=26.0.0. It has no peer dependencies. Install @authup/core-http-kit as well when you use remote mode, for createClientTokenCreator.

Usage

Verify locally

import { TokenVerifier } from '@authup/server-adapter-kit';

const verifier = new TokenVerifier({ baseURL: 'https://auth.example.com' });

const data = await verifier.verify(token);
// data.sub, data.sub_kind, data.realm_id, data.realm_name, data.scope, data.exp

Without a creator the verifier checks the token itself:

  • the header's kid must be a UUID and the payload must carry a realm_id;
  • the key is fetched from GET /realms/<realm_id>/jwks/<kid>, so a key of another realm can never verify the token;
  • the signature, exp and the token kind are checked;
  • permissions is always [], since an access token does not carry them.

Verify remotely

import { createClientTokenCreator } from '@authup/core-http-kit';
import { TokenVerifier } from '@authup/server-adapter-kit';

const verifier = new TokenVerifier({
    baseURL: 'https://auth.example.com',
    creator: createClientTokenCreator(
        { id: process.env.AUTHUP_CLIENT_ID ?? '', secret: process.env.AUTHUP_CLIENT_SECRET ?? '' },
        { client: { baseURL: 'https://auth.example.com' } },
    ),
});

const data = await verifier.verify(token);
const canRead = data.permissions.some((permission) => permission.name === 'order_read');

With a creator the verifier sends the token to POST /token/introspect, authenticated with a token the creator mints (and mints again after a 401). The answer includes the subject's permissions. An inactive token throws.

Give your API's client the token_introspect permission. Without it the client may only introspect tokens issued to itself, and every other token is reported inactive.

Cache verified tokens

import { MemoryTokenCache, RedisTokenCache, TokenVerifier } from '@authup/server-adapter-kit';

const verifier = new TokenVerifier({
    baseURL: 'https://auth.example.com',
    cache: new MemoryTokenCache(),
});

const shared = new TokenVerifier({
    baseURL: 'https://auth.example.com',
    cache: new RedisTokenCache('redis://127.0.0.1:6379'),
    maxRemoteCacheTTL: 60,
});

Verified results are cached only when you pass a cache. A result is kept for the token's remaining lifetime, or at most maxRemoteCacheTTL seconds in remote mode. Entries are keyed by a SHA-256 hash of the namespace and the token, the namespace defaulting to authup:<local|remote>:<baseURL>. MemoryTokenCache (re-exported from vouchly) keeps up to 10000 entries in process memory. RedisTokenCache takes a connection string, a redis-extension client, or nothing (redis-extension's default connection). A cache of your own implements vouchly's ITokenCache (get(key) and set(key, entry, ttl)).

Signing keys are never stored in cache: they stay in process memory, since a CryptoKey cannot be serialized.

Bound tokens

const bound = await verifier.verify(token, {
    certificateThumbprint: () => thumbprintOfPresentedCertificate(),
});

A token carrying cnf (RFC 8705) fails unless certificateThumbprint resolves to the SHA-256 DER thumbprint in cnf.x5t#S256. The provider is only called for such tokens, and the check runs on every call, cached results included.

Parse the Authorization header

import { extractBearerToken } from '@authup/server-adapter-kit';

const value = extractBearerToken(authorizationHeader); // undefined when the header is absent

It throws BearerTokenMalformedError (bearer_token_malformed, HTTP 401) for a header without a space, a scheme other than Bearer (case-insensitive), or an empty value.

Options

new TokenVerifier(context):

OptionTypeDefaultDescription
baseURLstring(required)Base URL of the Authup API
creatorTokenCreatorundefinedSwitches to remote mode: mints the token the introspection call authenticates with
cacheITokenCache | falseundefinedCaches verified results; without it every call verifies again
cacheNamespacestringauthup:<local|remote>:<baseURL>Separates the entries of verifiers sharing one cache. Only verifiers with the same configuration may share a namespace
maxRemoteCacheTTLnumberremaining token lifetimeUpper bound in seconds for caching a remote result
jwkCache{ ttl?, timeout? } | false{ ttl: 300, timeout: 10 }Signing key cache for local mode, held in process memory. ttl is seconds a key stays cached (0 stores nothing), timeout the seconds a key fetch may take. false fetches the key on every verification

verify(token, options):

OptionTypeDefaultDescription
certificateThumbprintstring | () => string | undefined | Promise<string | undefined>undefinedThumbprint of the presented client certificate, or a lazy provider for it

API

ExportKindPurpose
TokenVerifierclassverify(token, options?)
ITokenVerifierinterfaceThe verify(token, options?) contract the adapters accept
MemoryTokenCacheclassIn-process ITokenCache with per-entry TTL (re-exported from vouchly)
RedisTokenCacheclassRedis-backed ITokenCache
ITokenCache, TokenCacheEntrytypesvouchly's cache contract, for a cache of your own
extractBearerTokenfunctionReads the token out of an Authorization header value
assertTokenCertificateBindingfunctionThe RFC 8705 thumbprint check on its own
TokenVerifierContext, TokenVerifyOptions, TokenVerificationDatatypesOptions and result shapes

Notes

  • Local mode does not see revocations. A token whose session was revoked keeps verifying until it expires, and a disabled signing key keeps verifying until its cache entry expires (5 minutes by default). Use remote mode, or a short jwkCache.ttl, where that matters.
  • Errors are JWTErrors. A bad signature, missing claim or wrong kind throws invalid_token, an expired token expired_token, an inactive one inactive_token. In remote mode every other failure is invalid_token; the server's own error code is not passed through.
  • Results are copies. verify returns a clone, so mutating it never changes a cached entry.
  • Kind-less tokens pass. Only a present kind other than access_token is rejected.

License

Made with 💚

Published under the Apache 2.0 License.

版本与发布记录

@authup/server-adapter-kit 共发布 48 个版本,首次发布于 2024/10/04;过去 12 个月发布了 43 个版本。

版本发布日期距今
1.0.0-beta.73latest2026/11/025 天前
1.0.0-beta.722026/10/2711 天前
1.0.0-beta.712026/10/2018 天前
1.0.0-beta.702026/10/1919 天前
1.0.0-beta.692026/10/1424 天前
1.0.0-beta.682026/09/251 个月前

关于 @authup/server-adapter-kit 的常见问题

@authup/server-adapter-kit 是什么?

Verify Authup access tokens in your own API, locally against realm keys or by introspection.

如何安装 @authup/server-adapter-kit?

在项目目录运行 npm install @authup/server-adapter-kit,或使用 pnpm add / yarn add / bun add。

@authup/server-adapter-kit 支持 TypeScript 吗?

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

@authup/server-adapter-kit 支持 ESM 还是 CommonJS?

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

@authup/server-adapter-kit 需要什么版本的 Node.js?

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

@authup/server-adapter-kit 可以商用吗?

@authup/server-adapter-kit 使用 Apache-2.0 许可。宽松许可:允许商业使用、修改和再分发,并附带明确的专利授权;分发时需保留许可与 NOTICE 文件,修改过的文件要注明改动。以上为概括,不构成法律意见,请以许可原文为准。

@authup/server-adapter-kit 的下载量有多少?

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

@authup/server-adapter-kit 还在维护吗?

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