十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

Litestar 服务端会话(Server-Side Session):基于 Store 的会话中间件完整指南

Litestar 服务端会话(Server-Side Session):基于 Store 的会话中间件完整指南 Litestar 服务端会话Server-Side Session基于 Store 的会话中间件完整指南【免费下载链接】litestarLight, flexible and extensible ASGI framework | Built to scale项目地址: https://gitcode.com/GitHub_Trending/li/litestar本篇技术指南围绕 Litestar 的litestar.middleware.session.server_side模块展开系统讲解服务端会话的架构、配置参数、会话生命周期与底层实现。服务端会话将数据保存在服务器端的 Store 中内存、文件、Redis 或 Valkey客户端仅持有随机会话 ID 的 Cookie适用于登录态、购物车等需要服务端可控与可撤销的会话场景。读完本文你将掌握如何配置ServerSideSessionConfig、接入各类 Store、自定义会话 ID 生成与过期策略并理解SessionMiddleware在 ASGI 层的完整工作流程。一、什么是服务端会话Litestar 内置的 SessionMiddleware 同时支持客户端会话与服务端会话两种模式客户端会话Client-side会话数据经加密后存放在客户端 Cookie 中由ClientSideSessionBackend提供数据不占用服务端存储服务端会话Server-side会话数据保存在服务器端客户端 Cookie 中仅存放一个随机生成的会话 IDsession ID服务端据此从 Store 中加载对应的会话数据。正如 docs/usage/middleware/builtin-middleware.rst 中所述服务端会话由 Litestar 的 Store 体系提供底层支撑开箱支持四类存储后端内存会话In-memory文件会话File basedRedis 会话Valkey 会话服务端会话的最大优势在于服务端可控性会话数据不会暴露给客户端、可以随时在服务端删除或失效、天然规避了客户端篡改 Cookie 的风险同时不依赖加密密钥的同步分发。二、快速上手最小可运行配置ServerSideSessionConfig是服务端会话的配置入口其middleware属性会生成一个DefineMiddleware实例可直接挂载到应用的中间件栈中。以文件 Store 为例源码参考 docs/examples/middleware/session/file_store.pyfrom pathlib import Path from litestar import Litestar from litestar.middleware.session.server_side import ServerSideSessionConfig from litestar.stores.file import FileStore app Litestar( middleware[ServerSideSessionConfig().middleware], stores{sessions: FileStore(pathPath(session_data))}, )这里的关键点是ServerSideSessionConfig默认从应用 Store 注册表中读取名为sessions的 Store见下方store字段因此在应用上必须注册同名的 Store否则会话数据无处存放。启动应用后在路由处理器中即可通过request.session读写会话数据from litestar import Request, get get(/) def my_handler(request: Request) - dict: counter request.session.get(counter, 0) 1 request.session[counter] counter return {counter: counter}三、完整配置参数详解ServerSideSessionConfig是一个继承自BaseBackendConfig的 dataclass定义见 litestar/middleware/session/server_side.py其全部可配置字段如下表所示字段类型默认值说明session_id_bytesint32生成随机会话 ID 所使用的字节数renew_on_accessboolFalse访问会话时是否顺延其过期时间滑动过期keystrsession存放会话 ID 的 Cookie 名称例如sessionidmax_ageintONE_DAY_IN_SECONDS * 1414 天Cookie 的有效时长秒超过后失效scopesScopes{ScopeType.HTTP, ScopeType.WEBSOCKET}中间件生效的 ASGI 作用域默认 HTTP 与 WebSocket 均生效pathstr/Cookie 有效的 URL 路径片段domainstr \| NoneNoneCookie 生效的域名secureboolFalse是否仅允许 HTTPS 下传输 CookiehttponlyboolTrue禁止 JavaScript 通过Document.cookie访问samesiteLiteral[lax, strict, none]lax跨站请求时是否携带 Cookie默认laxexcludestr \| list[str] \| NoneNone会话中间件需要跳过的路径匹配模式单个或列表exclude_opt_keystrskip_session路由级禁用会话中间件的标识键storestrsessions会话数据存放的 Store 名称3.1 配置校验逻辑ServerSideSessionConfig在__post_init__中对关键参数做了运行时校验见 litestar/middleware/session/server_side.pykey的长度必须在1 到 256 个字符之间否则抛出ImproperlyConfiguredExceptionmax_age必须大于 0否则抛出ImproperlyConfiguredException。这保证了 Cookie 名称的合法性以及过期时间配置的合理性避免出现立即失效或格式非法的 Cookie。3.2 Cookie 参数与 BaseBackendConfig 的关系客户端与服务端会话共享绝大部分 Cookie 配置区别仅在于 Cookie 中存放的是加密数据还是会话 ID。这些公共字段定义在基类 litestar/middleware/session/base.py 的BaseBackendConfig中包括key、max_age、scopes、path、domain、secure、httponly、samesite、exclude、exclude_opt_key。服务端会话在此基础上额外增加了session_id_bytes、renew_on_access与store三个专属字段。3.3 排除特定路由通过exclude可以按路径模式跳过会话中间件更精细的做法是使用exclude_opt_key在某个路由上设置对应的 opt 标识即可为该路由单独禁用会话中间件。默认的标识键为skip_session可在路由处理器上这样使用from litestar import get get(/public, skip_sessionTrue) async def public_endpoint() - dict: return {message: no session for this route}四、Store 存储后端内存、文件、Redis、Valkey服务端会话的数据落点由 Litestar 的 Store 体系决定详见 docs/usage/stores.rst。ServerSideSessionConfig.store字段只指定 Store 的名称实际实例通过app.stores.get(self.store)从应用的 Store 注册表获取见 litestar/middleware/session/server_side.py。这意味着你可以无缝切换不同的存储后端只需修改stores注册即可。例如使用内存 Storefrom litestar import Litestar from litestar.middleware.session.server_side import ServerSideSessionConfig from litestar.stores.memory import MemoryStore app Litestar( middleware[ServerSideSessionConfig().middleware], stores{sessions: MemoryStore()}, )使用 Redis 或 Valkey 时对应的 Store 类位于 litestar/stores/redis.py 与 litestar/stores/valkey.py只需将 Store 实例以sessions为键注册进stores即可中间件配置完全不变。这种“配置与实现解耦”的设计让从开发期的内存会话平滑迁移到生产环境的 Redis/Valkey 会话成为可能。五、会话生命周期与底层实现剖析服务端会话的完整生命周期由SessionMiddleware与ServerSideSessionBackend协作完成两者分别定义在 litestar/middleware/session/base.py 与 litestar/middleware/session/server_side.py。5.1 请求进入加载会话数据SessionMiddleware.__call__是 ASGI 入口其核心流程见 litestar/middleware/session/base.py基于传入的 ASGIscope、receive、send构造ASGIConnection调用backend.load_from_connection(connection)将结果写入scope[session]此后路由处理器中request.session读取的就是这份数据通过backend.get_session_id(connection)确定本次请求的会话 ID并存入连接状态供响应阶段使用调用下游应用同时用create_send_wrapper包装send函数以便在响应发出前写入 Cookie。load_from_connection的实现逻辑见 litestar/middleware/session/server_side.py从请求 Cookie 中按config.key取出会话 ID若存在会话 ID则调用backend.get(session_id, store)从 Store 加载原始字节数据数据存在则通过deserialize_data反序列化为字典返回否则返回空字典。5.2 会话 ID 的获取与生成get_session_id见 litestar/middleware/session/server_side.py按以下优先级确定会话 ID优先读取请求 Cookie 中config.key对应的值值为null时视为无会话其次从连接状态中读取会话已创建但尚未通过响应写回客户端若两者皆无则调用generate_session_id()生成新 ID。generate_session_id使用 Python 标准库secrets.token_hex生成随机十六进制字符串字节数由session_id_bytes控制默认为 32 字节见 litestar/middleware/session/server_side.py。secrets模块专为密码学安全随机数设计保证了会话 ID 的不可预测性是防会话劫持与暴力枚举的基础。5.3 响应发出写回会话与 Cookiecreate_send_wrapper包装了 ASGIsend函数见 litestar/middleware/session/base.py当检测到http.response.start消息时调用backend.store_in_message(scope_session, message, connection)由后端决定如何持久化会话并设置Set-Cookie头。store_in_message的分支逻辑见 litestar/middleware/session/server_side.py会话为空scope_session is Empty调用delete删除 Store 中该会话 ID 对应的数据并设置值为null、expires0的 Cookie指示客户端立即清除会话 Cookie会话有数据先通过serialize_data将会话字典序列化为字节再调用set写入 Store同时向响应头添加携带会话 ID 的Set-Cookie。Cookie 的其余属性path、domain、secure、httponly、samesite等由extract_dataclass_items从配置中提取并合并进 Cookie 构造从而保证响应 Cookie 与配置完全一致。5.4 序列化机制会话数据在写入 Store 前通过BaseSessionBackend.serialize_data使用encode_json序列化为字节读取时经deserialize_data使用decode_json还原为字典见 litestar/middleware/session/base.py。序列化时优先从 ASGIscope提取自定义序列化器否则回退到默认序列化器这为自定义类型提供了扩展点。六、过期策略固定过期与滑动过期会话过期由max_age与renew_on_access两个参数共同决定固定过期max_age默认为 14 天ONE_DAY_IN_SECONDS * 14其中ONE_DAY_IN_SECONDS 60 * 60 * 24见 litestar/middleware/session/base.py。会话创建后无论用户如何访问都会在固定时长后失效滑动过期renew on access设置renew_on_accessTrue后每次访问会话都会顺延过期时间适合“活跃用户保持登录长期不活跃则自动登出”的场景。底层实现中get方法在读取数据时传入renew_for参数见 litestar/middleware/session/server_side.pymax_age int(self.config.max_age) if self.config.max_age is not None else None return await store.get(session_id, renew_formax_age if self.config.renew_on_access else None)当renew_on_access为True时每次读取都会以max_age为新的过期时长刷新 Store 中的记录从而实现滑动过期。七、后端接口契约与扩展点ServerSideSessionBackend继承自抽象基类BaseSessionBackend其职责是定义“存储机制”与“会话中间件”之间的接口见 litestar/middleware/session/base.py。ServerSideSessionBackend实现的四个核心方法构成了完整的存储契约方法签名作用getasync get(session_id, store) - bytes \| None按会话 ID 从 Store 读取原始数据不存在返回Nonesetasync set(session_id, data, store)将序列化数据写入 Store 并重置过期时间deleteasync delete(session_id, store)删除指定会话 ID 的数据ID 不存在时静默失败load_from_connectionasync load_from_connection(connection) - dict从连接 Cookie 提取会话 ID 并加载反序列化后的会话字典前三个方法均是 Store 接口的薄封装真正的读写、过期与删除逻辑由 Store 实现Store.get、Store.set、Store.delete见 litestar/stores/base.py。由于ServerSideSessionBackend本身就是为子类化设计的基类其 docstring 明确说明“subclasses can implement to facilitate the storage of session data”若内置的内存/文件/Redis/Valkey 后端无法满足需求可以继承ServerSideSessionConfig与ServerSideSessionBackend实现自定义的服务端会话后端接入其他存储系统。八、会话安全注意事项结合源码中的 Cookie 属性默认值服务端会话在生产环境应关注以下安全基线httponlyTrue默认阻止 JavaScript 读取会话 Cookie降低 XSS 窃取会话的风险secureTrue在纯 HTTPS 环境下应开启防止会话 ID 在明文 HTTP 中传输被截获samesitelax默认阻止大多数跨站请求携带会话 Cookie是缓解 CSRF 的基础防线之一session_id_bytes32默认 32 字节的密码学安全随机 ID 已具备足够的熵值不应为了“缩短 Cookie”而大幅调低服务端会话数据保存在服务端 Store即使 Cookie 被篡改或伪造也只会得到一个不存在的会话 ID无法伪造会话内容本身。九、总结服务端会话是 Litestar 面向“数据需要服务端掌控”场景的会话方案。通过ServerSideSessionConfig一行配置即可接入内存、文件、Redis、Valkey 等 Store 后端会话 ID 由secrets密码学安全随机数生成数据以 JSON 形式序列化存储。SessionMiddleware在 ASGI 请求入口将会话载入scope[session]并在响应阶段依据会话状态决定写入会话 Cookie 或清除 Cookie。其可配置的过期策略固定/滑动、路由级排除机制与后端扩展接口使其既能满足轻量开发需求也能支撑生产级会话管理。如需进一步了解底层实现可深入阅读 litestar/middleware/session/server_side.py、litestar/middleware/session/base.py 以及 Store 体系文档 docs/usage/stores.rst对应的单元测试位于 tests/unit/test_middleware/test_session/test_server_side_backend.py可用作行为验证的参考。【免费下载链接】litestarLight, flexible and extensible ASGI framework | Built to scale项目地址: https://gitcode.com/GitHub_Trending/li/litestar创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表