Обновить сессию#
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 |
Когда он выполняется |
Что происходит с вызовом |
|---|---|---|
|
До отправки |
Запрос уходит один раз с новой сессией |
Защищённый ответ дал |
После первого ответа |
Запрос повторяется в пределах |
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