Repository navigation
feat(account): refresh-токены с ротацией и отзывом (итер. 36) - #41
Merged
Merged
Conversation
…итер. 36)
Короткоживущий access-токен (join + API, формат и Verify не тронуты) обновляется
долгоживущим refresh-токеном с ротацией, серверным хранением и детекцией
переиспользования — теперь сессию можно отозвать (logout), а утёкший access живёт
максимум accessTTL.
- store: миграция 0002 (sqlite+postgres) refresh_tokens (в БД только SHA-256,
family_id — цепочка ротаций); методы CreateRefreshToken/RefreshTokenByHash/
RotateRefreshToken (tx: атомарный отзыв старого + вставка нового, при уже отозванном
ErrTokenRevoked)/RevokeRefreshFamily; уборка просроченных в ротации.
- account: NewService(store, secret, accessTTL 15m, refreshTTL 720h); Register/Login/
Guest → Tokens{Access,Refresh,ExpiresIn} (гость без refresh); Refresh (ротация;
повторное предъявление отозванного гасит семейство) и Logout.
- api: POST /api/refresh (под рейт-лимитом) + POST /api/logout (204); в ответы
register/login добавлены refresh_token + expires_in.
- cmd/server: env ARENA_ACCESS_TTL/ARENA_REFRESH_TTL вместо ARENA_TOKEN_TTL.
- web: хранит оба токена, обновляет access перед join и по 401, logout отзывает refresh.
- docs: README RU/EN + architecture.
Провод/симуляция не тронуты (игровые стражи не гонялись); security-review — findings
нет. make check + integration зелёные.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Что
Итерация 36 — refresh-токены + ротация + хардненинг auth. Один самодостаточный
HMAC-токен (TTL 24 ч) для API и game-join разбит на короткий access (формат и
Verifyне тронуты — join прежний) + долгий refresh с ротацией, сервернымхранением и детекцией переиспользования.
Зачем
Раньше утёкший токен был валиден сутки, а отозвать сессию / разлогинить на сервере
было нельзя. Теперь: access живёт максимум
accessTTL(деф. 15m), refresh отзывается(logout), а повторное предъявление отозванного refresh гасит всё семейство (детект кражи).
Как
0002(sqlite+postgres)refresh_tokens: в БД только SHA-256токена,
family_id— цепочка ротаций одного логина. МетодыCreateRefreshToken,RefreshTokenByHash,RotateRefreshToken(транзакция: атомарный отзыв старого +вставка нового; при уже отозванном →
ErrTokenRevokedбез вставки),RevokeRefreshFamily;просроченные токены аккаунта чистятся в той же ротации (таблица ограничена сроком жизни).
NewService(store, secret, accessTTL 15m, refreshTTL 720h);Register/Login/Guest→Tokens{Access, Refresh, ExpiresIn}(гость эфемерен — безrefresh);
Refresh(ротация; отозванный → гасим семейство) иLogout. Access остаётсяHMAC (constant-time
hmac.Equal), refresh —crypto/rand32B, хранится как SHA-256.POST /api/refresh(под рейт-лимитом — минтит токены) +POST /api/logout(204, идемпотентно); в ответы register/login добавлены
refresh_token+expires_in.Единый
ErrBadToken→401 для невалидного/просроченного/переиспользованного (без энумерации).ARENA_ACCESS_TTL/ARENA_REFRESH_TTLвместоARENA_TOKEN_TTL.(
ensureFreshAccess/refreshAccess), logout отзывает refresh на сервере.docs/architecture.md.Границы
Провод (
internal/protocol) и симуляция не тронуты (access-токен и join те же) →игровые стражи (concurrency/determinism/protocol) не гонялись (прецедент итер. 21).
Это бэкенд-фича безопасности → прогнан security-review: HIGH/MEDIUM-findings нет.
Тестирование
make check(vet +-raceвсе пакеты) — зелёный.make integration— зелёный.store(жизненный цикл refresh, ротация,ErrTokenRevoked, отзывсемейства, уборка просроченных — на SQLite; Postgres-сьют дополнен
refresh_tokens),account(ротация, детект переиспользования гасит семейство, logout, невалидный/просроченный refresh, гость без refresh),
api(эндпоинты refresh/logout, реюз→401,logout→204),
cmd/server(TestAuthTTLConfig).семейство погашено)→logout(204); гость без
refresh_token.node --check web/game.js.BENCHMARKS.md не трогался — горячего пути нет.