尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

remix 会话存储实战:使用 createMemcacheSessionStorage 将 Session 数据持久化到 Memcache

remix 会话存储实战:使用 createMemcacheSessionStorage 将 Session 数据持久化到 Memcache remix 会话存储实战使用 createMemcacheSessionStorage 将 Session 数据持久化到 Memcache【免费下载链接】remixThe fully-stacked web framework项目地址: https://gitcode.com/GitHub_Trending/re/remix导读session-storage-memcache是 remix 框架The fully-stacked web framework官方提供的 Memcache 会话存储实现它基于remix/session的核心 Session 抽象将会话数据持久化到外部 Memcache 服务器从而支持多实例水平扩展与进程重启后的会话保持。本文围绕 packages/session-storage-memcache/README.md 展开完整讲解安装方式、createMemcacheSessionStorage的全部配置项、底层 Memcache 文本协议客户端实现、TTL 与 Key 的设计细节并结合仓库内的单元测试与集成测试给出可验证的使用模式。读完本文你将能够在自己的 remix 应用中接入 Memcache 会话存储理解其生命周期与安全语义会话固定攻击防护、销毁、flash 消息等。一、安装与引入该包随 remix 主包一同发布安装方式与 remix 核心一致npm i remix安装后通过子路径导入工厂函数import { createMemcacheSessionStorage } from remix/session-storage/memcache从仓库源码看包的入口 src/index.ts 只导出两个符号工厂函数createMemcacheSessionStorage与选项类型MemcacheSessionStorageOptionstype导出。包的元数据定义在 packages/session-storage-memcache/package.json其唯一运行时依赖是remix-run/sessionworkspace 内联依赖即核心 Session 原语与存储接口。二、最小可用示例官方 README 给出的最小示例即完整可用import { createMemcacheSessionStorage } from remix/session-storage/memcache let sessionStorage createMemcacheSessionStorage(127.0.0.1:11211, { keyPrefix: my-app:session:, ttlSeconds: 60 * 60 * 24 * 7, })第一个参数是 Memcache 服务器的host:port字符串第二个参数是可选的配置对象。sessionStorage实现了SessionStorage接口read/save与 remix 其他存储cookie、memory、fs完全一致的用法读请求 Cookie → 修改会话 → 保存并写回Set-Cookie。README 特别提示Memcache 存储基于 TCP Socket 实现需要 Node.js 运行时详见下文底层客户端实现。三、配置项详解MemcacheSessionStorageOptions接口定义在 src/lib/memcache-storage.ts共三个可选字段配置项默认值类型说明useUnknownIdsfalseboolean是否复用客户端发来的、在存储中不存在的会话 IDkeyPrefixremix:session:string写入 Memcache 的所有 key 的前缀ttlSeconds0number会话过期时间秒0表示永不过期3.1 useUnknownIds未知会话 ID 是否复用读取时若 Cookie 中携带的会话 ID 在存储中不存在默认会生成一个全新的 ID丢弃客户端传来的未知 ID开启useUnknownIds: true后则沿用客户端传来的 ID。测试 memcache-storage.test.ts 中 does not use unknown session IDs by default 与 uses unknown session IDs if enabled 两条用例分别验证了这两种行为。该选项的典型价值在于配合客户端保持原会话 ID 的场景例如移动端弱网重试但需要注意安全性权衡默认关闭更安全避免接受任意客户端指定的 ID。3.2 keyPrefixKey 前缀与合法性校验默认前缀为remix:session:源码常量DEFAULT_KEY_PREFIX前缀只能包含可打印 ASCII 且不含空格的字符否则工厂函数直接抛错前缀加上 64 位十六进制哈希后不能超过250 字节Memcache key 长度上限因此前缀最多250 - 64 186字节。对应的两个校验函数assertValidKeyPrefix/assertValidTtl就在 src/lib/memcache-storage.ts 中测试用例 throws for invalid configuration 用keyPrefix: invalid prefix含空格验证了前缀校验逻辑。3.3 ttlSeconds过期时间语义默认0表示永不过期必须是非负整数否则抛错ttlSeconds: -1的测试用例验证了这一点超过 30 天2592000 秒的 TTL 会被转换为 Unix 时间戳。这是因为 Memcache 协议规定相对过期时间上限为 30 天超过后必须传绝对时间戳。实现在客户端 memcache-client.ts 的getMemcacheExpirationttlSeconds MAX_RELATIVE_EXPIRATION_SECONDS时原样传入否则计算Date.now()/1000 ttlSeconds。四、从源码看实现原理4.1 存储结构ID 哈希化createMemcacheSessionStorage内部逻辑src/lib/memcache-storage.ts会话数据以JSON 字符串形式存放在 Memcache实际 key 为keyPrefix SHA-256(id)64 位十六进制computeHash使用 Web Cryptocrypto.subtle.digest计算read解析 Cookie →client.get取回 JSON →JSON.parse恢复数据解析失败抛错并附上会话 ID 与错误信息save根据会话状态分三种情况——存在deleteIdregenerateId(true)触发先删除旧数据会话被destroyed删除当前数据并返回清空客户端 Cookie会话是dirty有修改client.set写回返回会话 ID 供 Cookie 使用均不满足则返回null不写 Cookie避免无意义流量。4.2 底层客户端纯 TCP 文本协议createMemcacheClientsrc/lib/memcache-client.ts使用 Node.jsnode:net实现了一个极简 Memcache 客户端未依赖任何第三方驱动每个命令建立独立 TCP 连接用完即socket.destroy()每次请求一条命令无连接池setNoDelay(true)关闭 Nagle 算法降低延迟连接与响应各设5 秒超时SOCKET_TIMEOUT_MS命令格式严格遵循 Memcache 文本协议get key\r\n、set key 0 exptime bytes\r\nvalue\r\n、delete key\r\n响应解析做了完整校验get响应必须是VALUE key flags bytes头 定长数据 END终止符长度、终止符、key 一致性都会校验不合法即抛 Invalid Memcache get response 类错误set只接受STOREDdelete接受DELETED或NOT_FOUND键不存在视为成功删除服务器地址解析通过new URL(memcache:// server)解析host:port端口省略时默认11211地址含路径、查询串、用户信息或非法端口非 1–65535 整数都会抛 Expected format host:port 错误。五、生命周期语义与安全实践结合 packages/session/README.md 中定义的 Session 语义Memcache 存储完整支持以下行为且均有测试覆盖见 memcache-storage.test.ts 与 memcache-storage.integration.test.ts跨请求持久化同一 Cookie 连续请求计数依次递增persists session data across requests销毁会话session.destroy()后数据被删除下一次请求拿到全新会话 ID计数重新从 1 开始clears session data when the session is destroyed未修改不写 Cookie会话未dirty时save返回null不会产生多余Set-Cookie头does not set a cookie when session data is not changedFlash 消息session.flash(message, success!)写入的数据仅在下一次请求可见之后即被消费makes flash data available only on the next request会话 ID 再生与防会话固定攻击登录等权限变更后应调用session.regenerateId()。默认旧数据保留在存储中leaves old session data in storage by default 用例验证需要删除旧数据时使用session.regenerateId(true)save时通过deleteId删除旧 key对应 deletes old session data when the id is regenerated and the deleteOldSession option is true 用例。注意regenerateId(true)对弱网移动端可能不利——客户端可能仍需用旧 ID 恢复会话TTL 超限仍可用ttlSeconds超过 30 天时客户端自动切换为绝对时间戳测试 preserves sessions when ttlSeconds exceeds Memcache relative expiration limit 验证了此场景。六、在请求管线中接入在生产代码中存储对象通常与session中间件配合使用。session中间件packages/session-middleware/src/lib/session.ts的职责是解析请求Cookie→ 调用sessionStorage.read把会话挂到请求上下文 → 响应阶段调用sessionStorage.save并把返回值序列化进Set-Cookie要求 Cookie 必须签名httpOnly默认开启。import { createCookie } from remix/cookie import { session } from remix/middleware/session import { createMemcacheSessionStorage } from remix/session-storage/memcache let sessionCookie createCookie(__session, { secrets: [s3cret], httpOnly: true }) let sessionStorage createMemcacheSessionStorage(127.0.0.1:11211, { ttlSeconds: 60 * 60 * 24 * 7, // 一周后过期 }) // 将 session 中间件接入 fetch-router 的中间件链 // 之后在处理器中通过 context.session 读取、修改会话使用session-storage-memcache后会话数据不再依赖单机内存或本地文件多个实例共享同一个 Memcache 集群即可保持登录态一致同时 TTL 由 Memcache 统一负责清理无需额外维护过期任务。运行时上请注意 README 的约束本存储依赖 Node.js 的 TCP Socketnode:net不适合无法使用 Node 网络栈的环境。七、测试与验证仓库为该包提供了三层测试可直接作为行为规范参考单元测试 memcache-client.test.ts用内存中的假 Memcache 服务器node:net实现验证 get/set/delete、未知 key 返回null、缺键删除视为成功以及非法地址、畸形响应、NOT_STORED、ERROR等错误路径存储测试 memcache-storage.test.ts覆盖上文全部生命周期语义与非法配置校验集成测试 memcache-storage.integration.test.ts连接真实 Memcache 服务器通过环境变量SESSION_MEMCACHE_INTEGRATION1与SESSION_MEMCACHE_SERVERhost:port开启未设置时自动跳过。运行测试的命令定义在 packages/session-storage-memcache/package.jsonpnpm testremix test或pnpm test:bun。八、与其他存储策略的对比依据 packages/session/README.md 中列出的存储策略可快速确定选型Memory仅测试/开发环境重启即丢无外部依赖Cookie数据全在 Cookie 中无需存储服务但受浏览器 4KB 大小限制Filesystem需要持久化文件系统适合单机、大数据量Memcache本文外部缓存服务多实例共享、进程重启不丢数据、TTL 自动清理适合需要水平扩展的生产环境数据量上限受 Memcache 单值大小默认 1MB约束。相关文档核心 Session 原语与存储接口packages/session/README.md会话中间件将存储接入请求处理packages/session-middleware/README.md本包实现源码memcache-storage.ts 与 memcache-client.ts本包许可证LICENSE【免费下载链接】remixThe fully-stacked web framework项目地址: https://gitcode.com/GitHub_Trending/re/remix创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表