tasks: закрыта задача oidc-login, заведён урожай ревью
This commit is contained in:
@@ -0,0 +1,54 @@
|
||||
# 🐞 Вести учёт употреблённых состояний входа на сервере
|
||||
|
||||
- **Тип:** fix
|
||||
- **Категория:** Очередь
|
||||
- **Зачем:** Одноразовость возврата держится на уборке куки, то есть на браузере: сервер не помнит, какие состояния уже потрачены.
|
||||
|
||||
Найдено ревью задачи `oidc-login` 2026-08-12, отчёт триажа —
|
||||
[review/report.md](../../openspec/changes/archive/2026-08-12-oidc-login/review/report.md),
|
||||
остаток пункта 4.
|
||||
|
||||
Носитель состояния здесь — кука, которую сервис ставит на время входа: в ней
|
||||
лежат выданное состояние и проверочный код, и по ней сверяется возврат.
|
||||
|
||||
Спека требует, чтобы состояние было одноразовым: возврат с уже употреблённым
|
||||
отвергается наравне с невыданным. Сегодня это выполняется тем, что носитель
|
||||
состояния убирается у браузера на возврате — и для обычного человека этого
|
||||
достаточно: второй раз тот же адрес возврата сверку не пройдёт.
|
||||
|
||||
Чего это не закрывает: тот, кто носитель контролирует, поставит его себе заново
|
||||
и повторит возврат. Отказ тогда наступит только потому, что код у провайдера
|
||||
одноразовый, — то есть гарантия перенесена на внешнюю систему, чего норма не
|
||||
допускает.
|
||||
|
||||
Цена сегодняшнего состояния невелика, поэтому задача и отложена: код живёт
|
||||
минуты, а вход у провайдера всё равно нужен. Цена решения — своё хранение
|
||||
состояний со сроком жизни и его чистка.
|
||||
|
||||
## Воспроизведение
|
||||
|
||||
1. Пройти вход до конца: получить сессию по возврату от провайдера.
|
||||
2. Поставить носитель состояния заново — тем же значением, которое сервис выдавал
|
||||
на первом шаге.
|
||||
3. Повторить тот же запрос возврата.
|
||||
4. Сверка состояния проходит, и запрос уходит в обмен. Отказ наступает только
|
||||
потому, что код у провайдера одноразовый, — то есть одноразовость держит
|
||||
внешняя система, а не сервис.
|
||||
|
||||
## Затрагивает
|
||||
|
||||
- обработчики начала входа и возврата;
|
||||
- место хранения употреблённых состояний: своя коллекция хранилища либо память
|
||||
процесса — выбор входит в задачу;
|
||||
- дельта-спека `access`, требование «Вход через внешнего провайдера» — сценарий
|
||||
«Возврат нельзя переиграть» получает настоящий оракул.
|
||||
|
||||
## Критерии приёмки
|
||||
|
||||
- Повторный возврат с тем же состоянием отвергается, даже если носитель
|
||||
восстановлен вручную. Оракул — тест: пройти вход, затем повторить тот же
|
||||
возврат с заново поставленным носителем; сессия не открывается.
|
||||
- Состояния не копятся без предела. Оракул — тест либо чтение кода: у записи
|
||||
состояния есть срок жизни, и просроченные убираются.
|
||||
- Вход по-прежнему проходит целиком. Оракул — существующий тест входа через
|
||||
подставного провайдера остаётся зелёным.
|
||||
Reference in New Issue
Block a user