Обновить сессию#

RefreshToken() отмечает значение для обновления, а ExpiresAt() позволяет сделать refresh до защищённого запроса. Если сервер всё же отвечает 401, runtime обновляет сессию и один раз повторяет исходный вызов.

→ Запрос · POST /auth/refresh

{"refresh_token": "refresh-1"}

← Ответ · 200 OK

{
  "access_token": "access-2",
  "refresh_token": "refresh-2",
  "expires_at": "2099-01-01T00:00:00Z"
}

LoginService.refresh(...) извлекает секрет из текущей модели и вызывает публичную refresh-операцию через тот же корень SDK.

# examples/docs/auth_lifecycle.py
class LoginService:
    async def acquire(
        self,
        credentials: LoginCredentials,
        context: AuthContext[MailSdk],
    ) -> UserSession:
        return await context.sdk.auth.login(
            email=credentials.email,
            password=credentials.password.get_secret_value(),
        )

    async def refresh(
        self,
        session: UserSession,
        context: AuthContext[MailSdk],
    ) -> UserSession:
        return await context.sdk.auth.refresh(
            refresh_token=session.refresh_token.get_secret_value(),
        )


class MailSdk(AsyncRoot):
    auth = api_group(AuthApi)
    account = api_group(AccountApi)

Пример начинает с сохранённого access-1. Сервер отклоняет его, после чего runtime вызывает refresh и повторяет GET /account с access-2.

# examples/docs/auth_refresh.py
async def main() -> None:
    site = AuthSite()
    async with mail_sdk(site, session=saved_session(access="access-1")) as sdk:
        account = await sdk.account.get_account()

    print(f"account: {account.id}")
    for call in site.calls:
        print(call)

Браузер хранит токен и срок в состоянии страницы; обновление одной сессии для нескольких вкладок показано в главе о браузерной сессии.

<!-- examples/mail/site/app.py -->
<main data-page="mailbox">
  <ul data-collection="messages">

Причина refresh

Когда он выполняется

Что происходит с вызовом

ExpiresAt() считает сессию просроченной

До отправки

Запрос уходит один раз с новой сессией

Защищённый ответ дал 401

После первого ответа

Запрос повторяется в пределах auth_retries

Refresh завершился ошибкой

Во время обновления

Старая revision не заменяется

Запускаемый файл целиком
"""Refresh and replay after a protected endpoint returns 401."""

import asyncio

from examples.docs.auth_lifecycle import AuthSite, mail_sdk, saved_session


# region docs: auth-refresh-run
# examples/docs/auth_refresh.py
async def main() -> None:
    site = AuthSite()
    async with mail_sdk(site, session=saved_session(access="access-1")) as sdk:
        account = await sdk.account.get_account()

    print(f"account: {account.id}")
    for call in site.calls:
        print(call)
# endregion docs: auth-refresh-run


if __name__ == "__main__":
    asyncio.run(main())
account: user-42
GET /account Bearer access-1
POST /auth/refresh
GET /account Bearer access-2

Дальше#