npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@ocenkamobi/om-oidc-client

v1.0.0

Published

Клиент сервисных аккаунтов auth.ocenka.mobi с кэшем токенов

Downloads

219

Readme

@ocenkamobi/om-oidc-client

Клиент сервисных аккаунтов auth.ocenka.mobi для серверов на Node 20+. Делает две вещи: аутентифицирует запрос к /token через client_secret_basic и кэширует ответ — одинаковый запрос получает тот же токен, пока тот не начнёт истекать.

Библиотека отвечает за авторизацию сервисных аккаунтов — про реализацию грантов в auth.ocenka.mobi ничего не знает.

Для CommonJS и Node 12 — @ocenkamobi/om-oidc-client-cjs.

Подключение

npm i @ocenkamobi/om-oidc-client
import { createOmOidcClient } from '@ocenkamobi/om-oidc-client'

export const oidc = createOmOidcClient({
  authority: 'https://auth.ocenka.mobi',
  clientId: process.env.CLIENT_ID!,
  clientSecret: process.env.CLIENT_SECRET!,
})

const { access_token } = await oidc.token({
  grant_type: 'client_credentials',
  resource: 'https://express.ocenka.mobi',
  scope: 'openid profile org express',
})

Клиент создаётся один на каждый сервисный аккаунт и держит отдельный кэш.

| опция | по умолчанию | значение | | -------------- | ------------ | --------------------------------------------------------------- | | authority | — | сервер авторизации, токены запрашиваются у ${authority}/token | | clientId | — | client_id сервисного аккаунта | | clientSecret | — | client_secret сервисного аккаунта | | minTtl | 60 | сколько секунд осталось в токене, чтобы его взяли из кэша | | maxEntries | 500 | сколько записей помещается в кэш |

Кэш

  • Ключ — тело запроса. Порядок полей и скоупов в scope значения не имеет, пустые поля не учитываются.
  • Токен отдаётся из кэша, пока ему осталось жить не меньше minTtl секунд. Срок берётся из expires_in.
  • Одновременные одинаковые запросы делают один сетевой вызов.
  • Из кэша вытесняются токены, которыми не пользуются: каждое чтение токена из кэша поднимает его.
  • Ошибки не кэшируются.
await oidc.token(body, { minTtl: 300 })  // токен нужен на долгую операцию
await oidc.token(body, { force: true })  // мимо кэша
oidc.invalidate(body)
oidc.clear()

Всё тело вызова await oidc.token(body) — это ключ для кэша. Все ключи хэшируются.

Отложенный токен (requested_token_type) выдаётся как любой другой ответ и кэшируется на свои 7 суток, но bearer-токеном не является: плагины его в заголовок не поставят, а кинут ошибку. Обменивать его на access-токен нужно самому — обычным запросом.

Ошибки

Отказ сервера — OmOidcTokenError с полями status, error, error_description. Ретраев нет. Запрос к /token прерывается через 10 секунд.

axios

import axios from 'axios'
import { attachToken } from '@ocenkamobi/om-oidc-client/axios'

const api = axios.create()
attachToken(api, oidc)

await api.get('https://express.ocenka.mobi/api/reports', {
  oidc: { grant_type: 'client_credentials', resource: 'https://express.ocenka.mobi' },
})

Токен ставится только запросам с oidc — без него заголовок не появится.

При необходимости параметры можно задать один раз: axios сливает конфиг инстанса с конфигом запроса, включая oidc.

const express = axios.create({
  oidc: { grant_type: 'client_credentials', resource: 'https://express.ocenka.mobi' },
})
attachToken(express, oidc)

await express.get('https://express.ocenka.mobi/api/orders') // с токеном
await express.get('https://express.ocenka.mobi/api/health', { oidc: false }) // без токена

attachToken возвращает функцию, снимающую интерцептор.

got

import got from 'got'
import { tokenHooks, withToken } from '@ocenkamobi/om-oidc-client/got'

const api = got.extend(tokenHooks(oidc))

await api.get('https://express.ocenka.mobi/api/reports', withToken({
  grant_type: 'client_credentials',
  resource: 'https://express.ocenka.mobi',
}))

withToken() кладёт параметры в context запроса. Без него токен не ставится.

Дефолт для инстанса задаётся тем же withToken() вторым аргументом extend, а снимается withToken(false):

const express = got.extend(
  tokenHooks(oidc),
  withToken({ grant_type: 'client_credentials', resource: 'https://express.ocenka.mobi' }),
)

await express.get('https://express.ocenka.mobi/api/orders')
await express.get('https://express.ocenka.mobi/api/health', withToken(false))