--- title: Войти и получить сессию description: Свяжите login-операцию с управляемой Bearer-сессией. sources: - eazy_sdk.auth.session_auth - eazy_sdk.auth.session_scheme - eazy_sdk.auth.Bearer api_fingerprint: "sha256:8e23dfe7e5ea90feea2bf451de76be42c5c677d853ad5aefae951b57b4f3a7e1" --- Управляемая сессия выполняет login перед первым защищённым вызовом. Приложение передаёт `LoginCredentials`, а `LoginService` вызывает обычную объявленную операцию и возвращает `UserSession`. :::::{grid} 1 1 2 2 :class-container: http-exchange :gutter: 2 ::::{grid-item} :class: http-panel http-panel--request **→ Запрос** · ``POST /auth/login`` ```json {"email": "ada@mail.example", "password": "correct-horse"} ``` :::: ::::{grid-item} :class: http-panel http-panel--response **← Ответ** · ``200 OK`` ```json { "access_token": "access-1", "refresh_token": "refresh-1", "expires_at": "2099-01-01T00:00:00Z" } ``` :::: ::::: :::::{tab-set} :sync-group: transport ::::{tab-item} HTTP :sync: http Модель отмечает роль каждого поля сессии. `session_scheme(...)` создаёт схему, которую можно поставить в `security` роутера. ```{literalinclude} ../../../../../../examples/docs/auth_lifecycle.py :language: python :start-after: "# region docs: auth-lifecycle-models" :end-before: "# endregion docs: auth-lifecycle-models" ``` Login и refresh остаются обычными публичными операциями, а защищённый роутер использует `USER_SESSION` по умолчанию. ```{literalinclude} ../../../../../../examples/docs/auth_lifecycle.py :language: python :start-after: "# region docs: auth-lifecycle-operations" :end-before: "# endregion docs: auth-lifecycle-operations" ``` `acquire(...)` получает типизированный `context.sdk`. Корень объявляет обе группы один раз. ```{literalinclude} ../../../../../../examples/docs/auth_lifecycle.py :language: python :start-after: "# region docs: auth-lifecycle-service" :end-before: "# endregion docs: auth-lifecycle-service" ``` Первый защищённый вызов запускает `acquire(...)`, сохраняет результат и повторно планирует операцию уже с `Authorization`. ```{literalinclude} ../../../../../../examples/docs/auth_login.py :language: python :start-after: "# region docs: auth-login-run" :end-before: "# endregion docs: auth-login-run" ``` :::: ::::{tab-item} Браузер :sync: browser Браузерный вход начинается с реальной HTML-формы, а пошаговые операции `BrowserLogin` разобраны в {doc}`главе учебного примера `. ```{literalinclude} ../../../../../../examples/mail/site/app.py :language: html :start-after: "" :end-before: "" ``` :::: ::::: | Ответ login | Правило | Что получает вызывающий | |---|---|---| | `200` с моделью сессии | `acquire(...)` завершён | Результат защищённого метода | | Отображённый `ApiError` | Сессия не сохранена | Типизированное исключение | | Неизвестный или повреждённый ответ | Разбор модели не выполнен | Ошибка протокола | :::{dropdown} Запускаемый файл целиком ```{literalinclude} ../../../../../../examples/docs/auth_login.py :language: python ``` ::: ```text account: user-42 ada@mail.example first request: POST /auth/login ``` `session_auth(...)` остаётся короткой формой для SDK без общей схемы роутера. В корне с несколькими группами используйте `session_scheme(...).configure(...)`, как в этом примере. ## Дальше - {doc}`Обновить сессию ` - {doc}`Повторно использовать сессию ` - {doc}`Исходы многошагового входа `