⟨/⟩ 55_Backend/Handlers/Auth/LogoutHandler.cs

51 строк · в начало

using System;
using Ban.Sdaid.Notation.Documents;
using Ban.Sdaid.Icd;
using Ban.Sdaid.Icd.Api.Endpoints.Auth.Logout;
using Ban.Sdaid.Icd.Domain.Access;

namespace Ban.Sdaid.Icd.Backend.Handlers.Auth
{
    /// <summary>Handler выхода (отзыв текущего токена).</summary>
    public class LogoutHandler : IHandlerDocument, IFolder<BackendFolder>, IHasStructuralLinks
    {
        public SdaidLink[] Links => new[]
        {
            Rel.Uses<Ban.Sdaid.Icd.Domain.BC_Icd>(),
            Rel.Uses<UserTokenSpec>(),
            Rel.Uses<DOC_Logout>(),
        };

        public static string _refName = "Handler Logout";

        public string Name => "Handler: Logout";

        public string Description =>
            @"Что произойдёт при вызове endpoint Logout: отозвать текущий токен по jti и вытеснить контекст пользователя из кэша.";

        public string Version => "0.1";
        public string Status => "draft";
        public string[] Comments => new string[0];

        public static string Purpose = $"""
            ## Назначение

            Канонический сценарий обработки {SdaidAnchors.RefTo<DOC_Logout>()}. Делает выход настоящим:
            токен перестаёт действовать сразу, не дожидаясь истечения. Claim-проверки нет — выйти вправе
            любой аутентифицированный.
            """;

        public static string Scenario = $"""
            ## Сценарий вызова

            1. Извлечь `jti` из токена в заголовке `Authorization`.
            2. Найти активный токен ({SdaidAnchors.RefTo<UserTokenSpec>()}) по `jti`. Не найден — `401`.
            3. Перенести запись в отозванные (`UserInvalidatedToken`, причина «выход») и убрать из активных.
            4. Вытеснить контекст пользователя из кэша по `jti`.
            5. Вернуть успех (`200`).

            После этого запрос с тем же токеном отклоняется middleware чёрного списка (`401`).
            """;
    }
}