Поддерживаемые среды: Node.js, Deno, браузер, Edge Runtime

Библиотека jose полностью поддерживает современный Node.js через нативные криптографические API и ESM-модули. Начиная с Node.js 16+ и особенно в версиях 18+, где стабилизирован Web Crypto API (globalThis.crypto), библиотека работает без дополнительных полифиллов.

Ключевая особенность интеграции — опора на стандарт Web Crypto API, а не на устаревший crypto из Node.js в синхронном стиле.

Основные моменты использования:

  • Поддержка только ESM (import вместо require)
  • Использование Uint8Array для всех криптографических операций
  • Работа через crypto.subtle

Пример базового использования:

import { SignJWT, jwtVerify } from 'jose'

const secret = new TextEncoder().encode('super-secret-key')

const jwt = await new SignJWT({ role: 'admin' })
  .setProtectedHeader({ alg: 'HS256' })
  .setIssuedAt()
  .setExpirationTime('2h')
  .sign(secret)

const { payload } = await jwtVerify(jwt, secret)

В Node.js важно учитывать:

  • Если используется версия Node.js ниже 18, необходимо явно подключать crypto.webcrypto:
import { webcrypto } from 'node:crypto'
globalThis.crypto = webcrypto
  • В средах с CommonJS требуется либо переход на ESM, либо динамический импорт:
(async () => {
  const { jwtVerify } = await import('jose')
})()

Node.js обеспечивает наиболее полную поддержку алгоритмов (HS256, RS256, ES256, EdDSA), включая работу с ключами в формате PEM и JWK.


Deno

Deno изначально ориентирован на Web API-совместимость, поэтому jose интегрируется с ним практически без адаптаций.

Особенности:

  • Полная поддержка Web Crypto API из коробки
  • Использование ESM URL-импортов
  • Отсутствие необходимости в пакетном менеджере

Пример импорта:

import { createRemoteJWKSet, jwtVerify } from 'https://deno.land/x/jose/index.ts'

Работа с JWT:

const JWKS = createRemoteJWKSet(
  new URL('https://example.com/.well-known/jwks.json')
)

const { payload } = await jwtVerify(token, JWKS)

Важные особенности Deno:

  • Нет необходимости в полифиллах crypto
  • Полная поддержка crypto.subtle
  • Жёсткая модель разрешений (permissions), поэтому доступ к сети и файлам нужно явно разрешать:
deno run --allow-net app.ts
  • Импорт через URL может кешироваться автоматически, что влияет на поведение версионирования jose

Deno является одной из самых “чистых” сред для jose, так как отсутствуют расхождения между Web Crypto API и runtime.


Браузер

В браузерной среде jose использует нативный Web Crypto API, доступный через window.crypto.subtle.

Поддерживаются современные браузеры:

  • Chrome / Edge (Chromium)
  • Firefox
  • Safari 15+

Ключевая особенность — работа строго в асинхронном режиме, так как криптографические операции основаны на Promise API.

Пример:

import { SignJWT, jwtVerify } from 'jose'

const secret = new TextEncoder().encode('browser-secret')

const token = await new SignJWT({ user: 'alice' })
  .setProtectedHeader({ alg: 'HS256' })
  .sign(secret)

const { payload } = await jwtVerify(token, secret)

Ограничения браузера:

  • Нет доступа к файловой системе для ключей (PEM нужно загружать вручную или конвертировать в JWK)
  • Ограничения CORS при загрузке JWKS
  • Невозможность использовать Node.js Buffer API — только Uint8Array

Типичный подход в браузере:

  • Хранение ключей в памяти или IndexedDB
  • Использование JWK вместо PEM
  • Загрузка публичных ключей через HTTPS

Пример загрузки JWKS:

import { createRemoteJWKSet, jwtVerify } from 'jose'

const JWKS = createRemoteJWKSet(
  new URL('https://auth.example.com/.well-known/jwks.json')
)

const { payload } = await jwtVerify(token, JWKS)

Браузерная среда делает jose особенно удобным для SPA и фронтенд-аутентификации.


Edge Runtime

Edge Runtime (например, Vercel Edge, Cloudflare Workers, Deno Deploy-подобные среды) представляет собой ограниченную, но высокопроизводительную среду, основанную на Web API.

Jose изначально хорошо подходит для edge-окружений благодаря отсутствию зависимости от Node.js встроенных модулей.

Особенности:

  • Используется только Web Crypto API
  • Нет fs, net, tls
  • Строгая оптимизация по размеру и времени выполнения
  • Полная ESM-ориентация

Пример для edge-функции:

import { jwtVerify } from 'jose'

export default async function handler(req) {
  const token = req.headers.get('authorization')?.replace('Bearer ', '')

  const secret = new TextEncoder().encode('edge-secret')

  const { payload } = await jwtVerify(token, secret)

  return new Response(JSON.stringify(payload), {
    headers: { 'content-type': 'application/json' }
  })
}

Использование JWKS на edge:

import { createRemoteJWKSet, jwtVerify } from 'jose'

const JWKS = createRemoteJWKSet(
  new URL('https://auth.example.com/jwks.json')
)

export default async function handler(req) {
  const token = req.headers.get('authorization')?.slice(7)

  const { payload } = await jwtVerify(token, JWKS)

  return new Response(payload.sub)
}

Ключевые ограничения Edge Runtime:

  • Ограниченный CPU time (обычно миллисекунды на запрос)
  • Нет синхронных операций
  • Ограничения на размер бандла
  • Отсутствие Node.js crypto-расширений

Преимущество jose в этом контексте — минимальный overhead и отсутствие необходимости в нативных бинарных зависимостях.


Сравнение поведения в разных средах

Внутренняя модель работы jose унифицирована, но поведение зависит от доступного криптографического backend:

  • Node.js: Web Crypto + fallback через Node crypto (в старых версиях)
  • Deno: чистый Web Crypto без адаптаций
  • Браузер: Web Crypto API напрямую
  • Edge Runtime: урезанный Web Crypto API без расширений

Общий контракт библиотеки остаётся одинаковым:

  • Все операции асинхронные
  • Все ключи представлены как CryptoKey или Uint8Array
  • Алгоритмы строго стандартизированы (JOSE RFC 7515–7519)

Такая унификация позволяет переносить один и тот же код между backend, frontend и edge-средами без изменения логики криптографии.