Skip to content

Основные концепции

Эта страница объясняет ключевые абстракции и модель проектирования CyberGo JWT, помогая построить общее понимание. Чтобы сразу перейти к практике, перейдите к Быстрому старту.

Processor — центральный тип

Processor — центральный тип библиотеки, создаваемый через jwt.New(cfg). Он инкапсулирует всю логику выдачи, проверки, обновления и отзыва токенов. Все методы потокобезопасны — один экземпляр можно разделять между горутинами.

Вызовите Close() после использования для безопасного очищения секретного ключа и освобождения ресурсов:

go
<!-- check-code: skip -->
cfg := jwt.DefaultConfig()
cfg.SecretKey = "your-32-byte-secret-key-here-minimum"

processor, err := jwt.New(cfg)
if err != nil {
    log.Fatal(err)
}
defer processor.Close()

Processor реализует интерфейс TokenManager, что позволяет использовать его для внедрения зависимостей и подмены в тестах.

Жизненный цикл токена

Токен проходит следующие этапы от выдачи до аннулирования:

text
Выдача  Create(claims)           → Токен доступа (краткосрочный)
        CreateRefresh(claims)     → Токен обновления (долгосрочный)

Проверка Validate(token)          → Claims (проверка подписи, срока, издателя, чёрного списка)

Обновление Refresh(refreshToken)  → Новый токен доступа

Отзыв   Revoke(token)             → Добавлен в чёрный список
Проверка IsRevoked(token)         → bool

Каждый этап возвращает сентинельные ошибки (например ErrTokenExpired, ErrTokenRevoked), которые можно точно сопоставить через errors.Is(). См. Обработка ошибок.

Двухуровневая модель токенов

CyberGo JWT использует дизайн с токеном доступа + токеном обновления:

Токен доступаТокен обновления
НазначениеАутентификация APIПолучение новых токенов доступа
TTL по умолчанию15 минут7 дней
Метод выдачиCreateCreateRefresh
Метод обновленияRefresh

Зачем два уровня? Токены доступа живут недолго, поэтому окно риска при утечке невелико. Токены обновления живут долго, но используются только для получения новых токенов доступа, никогда — для прямой аутентификации API. Этот дизайн балансирует безопасность и пользовательский опыт: пользователям не нужно часто входить в систему, а токены доступа можно обновлять автоматически после истечения.

Семантика ротации

Refresh не отзывает токен обновления автоматически. Исходный токен обновления остаётся действительным до истечения срока или явного вызова Revoke. Для семантики одноразового использования (ротация токенов обновления) вызовите Revoke для старого токена обновления после успешного Refresh. См. Обновление и ротация токенов.

Структура Claims

Claims переносят данные идентификации пользователя внутри токена. CyberGo JWT предоставляет двухуровневую структуру:

RegisteredClaims (стандартные claims RFC 7519, автоматическое заполнение и проверка):

ПолеclaimОписание
IssuerissИдентификатор издателя
SubjectsubИдентификатор субъекта (также ключ ограничения скорости)
AudienceaudЦелевая аудитория
ExpiresAtexpСрок действия
NotBeforenbfВремя начала действия
IssuedAtiatВремя выдачи
IDjtiУникальный идентификатор (ключ чёрного списка)
TokenTypetoken_typeaccess или refresh

Claims (встроенные бизнес-claims, встраивает RegisteredClaims):

go
<!-- check-code: skip -->
type Claims struct {
    UserID      string         // ID пользователя
    Username    string         // Имя пользователя
    Role        string         // Роль
    Permissions []string       // Список разрешений
    Scopes      []string       // OAuth-области
    SessionID   string         // ID сессии
    ClientID    string         // ID клиента
    Extra       map[string]any // Дополнительные поля
    RegisteredClaims           // Стандартные claims (встраивание)
}

Все поля проходят проверку ввода: ограничение длины строки 256, ограничение массива 100, обнаружение шаблонов инъекций (сигнатуры XSS/SQLi).

Интерфейс CustomClaims

Когда встроенные Claims не отвечают бизнес-требованиям, реализуйте интерфейс CustomClaims для определения собственной структуры claims:

go
<!-- check-code: skip -->
type AppClaims struct {
    UserID string   `json:"user_id"`
    TeamID string   `json:"team_id"`
    Roles  []string `json:"roles,omitempty"`
    jwt.RegisteredClaims
}

func (c *AppClaims) GetRegisteredClaims() *jwt.RegisteredClaims {
    return &c.RegisteredClaims
}

func (c *AppClaims) Validate() error {
    if c.UserID == "" {
        return errors.New("user_id is required")
    }
    return nil
}

Пользовательские типы проверяются через ValidateInto и обновляются через RefreshInto — Processor разбирает токен и заполняет вашу структуру. См. Пользовательские Claims.

Обзор Config

Config — единая точка конфигурации Processor. Начните с DefaultConfig() для разумных значений по умолчанию, затем задайте ключ подписи:

ГруппаПоляОписание
ПодписьSecretKey / SigningKey / VerificationKey / SigningMethodHMAC использует SecretKey; RSA/ECDSA использует SigningKey
ТокенAccessTokenTTL / RefreshTokenTTLВремя жизни токенов доступа и обновления
ПроверкаIssuer / ExpectedAudience / RequireExpiration / ClockSkewИздатель, аудитория, обязательный срок действия, допуск часов
БезопасностьBlacklist / EnableRateLimitХранилище отзывов и ограничение скорости
РасширениеClockВнедрение часов (для тестирования)

Выбор алгоритма см. в Алгоритмы подписи; полную документацию по полям — в Конфигурации.

Интерфейсы расширения

CyberGo JWT расширяется через интерфейсы:

ИнтерфейсНазначение
TokenManagerОсновной интерфейс, реализуемый Processor. Можно определить собственный подмножественный интерфейс (только Create + Validate) для внедрения зависимостей и слабой связанности
BlacklistStoreПользовательский бэкенд чёрного списка (например, Redis). Реализуйте Add / Contains / Close для подключения внешнего хранилища
RateLimitProviderПользовательский ограничитель скорости. Реализуйте Allow / Reset / Close для замены встроенного алгоритма token bucket
ClockProviderВнедрение часов. FixedClock возвращает фиксированное время для детерминированного контроля логики истечения и обновления в тестах

Следующие шаги