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

资讯详情

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

Folo Desktop v1.7.0 源码级解读:认证 Cookie 治理、OTA 更新决策与桌面导航修复

Folo Desktop v1.7.0 源码级解读:认证 Cookie 治理、OTA 更新决策与桌面导航修复 Folo Desktop v1.7.0 源码级解读认证 Cookie 治理、OTA 更新决策与桌面导航修复【免费下载链接】follow Folo is the AI RSS Reader项目地址: https://gitcode.com/GitHub_Trending/fol/follow本文面向桌面端开发者与 Folo 高级用户以 v1.7.0 官方变更日志 为骨架逐一深入其背后实现认证会话 Cookie 的去重与刷新、Mac App StoreMAS分发下的 OTA 更新判定、Discover 深链导航以及 API 请求超时策略。读完你会理解 Folo 桌面端主进程Electron main process在「登录态一致性」与「更新决策」两条链路中的真实工程细节并能据此排查自己桌面应用中遇到的重复 Cookie、登出/刷新失效、分发商店更新误报等同类问题。版本全景一次聚焦稳定性的桌面端迭代Folo 是一个跨平台的 AI RSS 阅读器Monorepo 见 packages 与 apps 结构桌面端应用位于 apps/desktop。v1.7.0 是一次典型的“稳定性迭代”变更日志apps/desktop/changelog/1.7.0.md内容如下Improvements移除桌面应用中的连接状态指示器No longer broken修复重复的桌面认证会话 Cookie修复 Cookie 更新后的会话刷新修复从 Discover 路由返回修复桌面下载链接修复从 OTA 版本检测 MAS 审核状态延长 API 请求超时其中绝大多数修复都落在主进程目录 apps/desktop/layer/main/src 的认证auth、auth-cookies与更新updater子系统中并配有对应单元测试如auth-cookies.test.ts、updater/api.test.ts、updater/index.test.ts因此可以用源码逐条还原“为什么会出现问题”与“现在如何被解决”。Improvements移除桌面连接状态指示器v1.7.0 在界面层面做减法去掉了桌面客户端里常驻的连接状态指示器让顶部布局更干净。从渲染层现状看主布局 MainDestopLayout.tsx 中只保留了对“环境”而非“网络连接”的提示仅当非生产环境!PROD时才渲染 EnvironmentIndicator.tsx——实际文件为 EnvironmentIndicator.tsx用于标识当前运行环境而非联网状态真正的网络连通性问题应通过请求超时、重试与同步队列如 SyncIndicator.tsx反馈给用户。此次移除意味着网络状态不再以常驻徽标干扰阅读主界面回归“阅读器优先”的交互断网感知职责转向具体操作的错误提示与自动重试。注此条为界面取舍代码上无对应“删除 diff”可引用以上为该组件当前职责与布局的描述可作为理解改动的背景。修复 1重复桌面认证会话 Cookie问题背景Folo 桌面端使用 better-auth 做账号体系。登录后服务端会种下多组 Cookie例如better-auth.session_token非安全前缀__Secure-better-auth.session_tokenSecure 前缀better-auth.session_data及配套的dont_remember、trust_device、two_factor等状态 Cookie由于桌面端需要同时支持「主窗口内登录」与「主进程直接携带 Cookie 调用 API」如果同一名称的 Cookie 因secure、hostOnly、domain、path差异在 Electron session 中出现多份拼装请求头时就会重复携带甚至互相覆盖导致鉴权不稳定出现重复的会话 Cookie。解决方案统一的受管 Cookie 清单 写入前清理 去重主进程 auth-cookies.ts 是该修复的核心实现。它把 better-auth 会写入的所有 Cookie 名集中收编const MANAGED_AUTH_COOKIE_NAMES [ BETTER_AUTH_SECURE_SESSION_TOKEN_COOKIE_NAME, BETTER_AUTH_SESSION_TOKEN_COOKIE_NAME, __Secure-better-auth.session_data, better-auth.session_data, better-auth.last_used_login_method, dont_remember, __Secure-better-auth.dont_remember, better-auth.dont_remember, trust_device, __Secure-better-auth.trust_device, better-auth.trust_device, two_factor, __Secure-better-auth.two_factor, better-auth.two_factor, ] as const关键设计有三点写入前先清旧值。applySessionToken()见 auth.ts在写入新 token 前会按名字removeManagedAuthCookies清掉旧session_token再以统一的path: /、httpOnly: true、sameSite: no_restriction写入最后调用去重例程。解析并复写服务端 Set-Cookie。persistManagedAuthCookiesFromSetCookieHeader()auth-cookies.ts手写了解析器splitSetCookieHeader()能正确处理Expires中带逗号的多段头对maxAge 0或已过期的 Cookie 只删不写写入后再统一dedupe。最终去重兜底。dedupeManagedAuthCookies()auth-cookies.ts对每个受管名字挑选“最优”的那份——评分函数getCookieHeaderPriority()认为hostOnly、值中含.、secure、path /更可信const getCookieHeaderPriority (cookie: ManagedAuthCookie) { let priority 0 if (cookie.hostOnly) priority 8 if (cookie.value.includes(.)) priority 4 if (cookie.secure) priority 2 if ((cookie.path ?? /) /) priority 1 return priority }此外一旦存在__Secure-better-auth.session_token非 Secure 前缀的旧session_token会被视为冗余而移除auth-cookies.ts保证发出请求时每种 Cookie 至多一份、且永远优先携带最可信的会话令牌。对应逻辑由 auth-cookies.test.ts 覆盖。修复 2Cookie 更新后的会话刷新问题背景修复 1 解决的是“Cookie 变多”修复 2 解决的是“Cookie 变了之后会话没跟上”。典型场景主进程在某次带认证的请求中收到服务端Set-Cookie例如刷新了 session token、或触发了 TOTP 验证后的会话升级但渲染层仍在用旧的会话缓存数据导致界面显示与真实登录态不一致甚至被服务端拒绝后才被迫重登。当前实现链路主进程在每次与认证相关的请求后都会持久化响应中的 Cookieauth.ts 的persistAuthCookiesFromResponse()会把set-cookie全量交给上文的管理器写入并去重它被requestCredentialAuth邮箱登录/注册、verifyTotp两步验证以及带认证的fetchWithAuth统一调用。会话变化后需要“通知”渲染层失效旧缓存。桌面渲染层把主进程能力通过window.expose暴露见 extension-expose-provider.tsxrefreshSession: invalidateUserSession,即主进程/深链触发的refreshSession最终映射为失效用户会话相关 query让 React Query 重新拉取最新登录态配套的sessionChanged()auth.ts还会把当前桌面会话同步到 npm 版 CLIfolocli的登录态相关实现见 cli-session-sync.ts 的syncSessionToCliConfig()。另外桌面端支持通过深链手动刷新会话协议路由处理器 router.ts 中/refresh会调用caller.refreshSession()这为「Cookie 更新后强制重刷」提供了外部触发入口。修复 3从 Discover 路由返回Discover 是 Folo 的 RSSHub/内容发现功能。修复点在于“从 Discover 路由返回”时的导航状态当用户通过协议深链或内部跳转进入 Discover 某个 RSSHub route 后再返回探索页应回到正确位置而不是丢失上下文或触发错误查询。相关实现与数据流主进程深链入口handleUrlRouting()对/discover?routexxx解析 route 参数并调用caller.rsshubRoute(route)router.ts渲染层暴露端rsshubRoute(route)的桥接处理位于 extension-expose-provider.tsx数据层Hook useDiscoverRSSHubRoute.tsx 通过useAuthQuery(discover.rsshubRoute({ route }))加载数据对应 API 封装在 queries/discover.ts。v1.7.0 的修复目标是确保这些路由状态在“进入 Discover → 加载某个 route → 返回”的闭环中保持一致。对该改动的精确 diff 无法从仓库只读现状还原但从上述调用链可见其职责边界主进程只负责解析协议并转发 route渲染层负责查询与返回态管理。修复 4桌面下载链接桌面端涉及“下载”的场景主要是应用/渲染层更新包的拉取。主进程提供了统一下载工具 download.tsdownloadFile(url, dest)基础流式下载非 2xx 直接抛错downloadFileWithProgress(options)进阶版支持目录自动创建、onLog日志回传、onProgress进度回调每 500ms 节流上报一次百分比与已下载/总 MB以及可选的SHA-256 哈希校验——服务端下发 manifest 时附带期望哈希下载完成后比对expectedHash不一致则返回失败并记录日志防止下载到被篡改或损坏的文件。if (expectedHash sha256) { sha256.update(buffer) const hash sha256.digest(hex) if (hash ! expectedHash) { onLog?.(Hash verification failed. Expected: ${expectedHash}, Got: ${hash}) return false } }Windows 平台另有一套基于electron-updater的实现windows-updater.ts 与 dev 模式使用的 dev-app-update.yml。v1.7.0 对“桌面下载链接”的修复即落在这些下载入口所指向 URL 的正确性上更新 feed 与发布产物地址保证用户能从桌面端打开正确的下载/安装来源。修复 5从 OTA 版本判定 MAS 审核状态这是本次修复中最“架构化”的一条涉及OTA 更新协议与商店分发MAS即 Mac App Store的协同。分发类型与开关桌面端在构建期区分分发渠道isStoreDistribution Boolean(process.mas || MICROSOFT_STORE_BUILD)updater/configs.ts由此决定走“直连分发direct”还是“商店分发mas/mss”的更新策略export const appUpdaterConfig { enableRenderHotUpdate: !DEV MODE ! ModeEnum.staging, enableCoreUpdate: !isStoreDistribution, enableAppUpdate: true, enableDistributionStoreUpdate: isStoreDistribution, app: { autoCheckUpdate: true, checkUpdateInterval: 15 * 60 * 1000 }, }商店分发的应用无法自行替换主程序包只能走两件事渲染层热更新OTA 引导用户去商店更新。调度入口在 updater/index.ts 的handleDistributionAppDecision()先尝试把服务端下发的 renderer 清单作为热更新应用若不需要或不允许再评估是否要提示商店更新。OTA 版本与审核状态的关系每次更新检查客户端都向 OTA 服务端上报自身“运行时版本”见 updater/api.tsexport const getDesktopRuntimeVersion () configuredRuntimeVersion ?? appVersion export const buildDesktopOtaHeaders (includeRenderer false) ({ ...createDesktopAPIHeaders({ version: PKG.version }), X-App-Channel: channel, X-App-Runtime-Version: getDesktopRuntimeVersion(), // includeRenderer 时追加 X-App-Renderer-Version })随后拉取两个端点/manifestOTA 热更清单含runtimeVersion、renderer、app载荷updater/api.ts/policy分发策略返回actionnone | prompt | block、distributiondirect | mas | mss、targetVersion、downloadUrl、storeUrl等updater/api.ts。对 MAS 用户而言一个关键的竞态是开发者向 App Store 提交了新版本但苹果仍处于审核期尚未上架。此时如果 OTA 服务端按“未来版本”判定当前客户端过旧就可能误导用户去商店找并不存在的更新。v1.7.0 修复的正是这种状态误判——客户端通过/manifest中的runtimeVersion而非简单的 app 版本号与服务端/policy协同正确识别“本地运行的是否是商店当前已批准发布的版本”只有当商店侧确实存在更新的已发布版本时才触发distributionUpdateAvailable提示。决策侧的逻辑可对应到 updater/index.tsshouldPromptDistributionStoreUpdate()要求分发类型非 direct、存在storeUrl、且action ! nonenotifyDistributionUpdate()再向渲染层广播distributionUpdateAvailable({ distribution, targetUrl, storeVersion, currentVersion })UI 据此展示“前往商店更新”弹层。对“商店构建禁止 OTA 主程序更新、仅允许渲染层热更”的边界tryDistributionRendererUpdate()updater/index.ts也用RendererEligibilityStatusAlreadyCurrent / RequiresFullAppUpdate / Eligible做了显式分流。相关解析与决策逻辑在 updater/api.test.ts含distribution: mas用例与 updater/index.test.ts 中有测试覆盖。修复 6延长 API 请求超时慢网络、大响应或代理环境会让原本偏紧的请求超时被过早触发表现为“接口偶发失败”。v1.7.0 做了放宽。从当前代码可见桌面端两类网络通道的默认超时配置渲染层到主进程的 API 客户端api-client.ts 中timeout: 10000ky 选项即 10 秒主进程自定义 fetch 通道供集成/扩展使用的带超时 fetchintegration.ts 中const { url, method, headers, body, timeout 10_000 } input超时后打印Request timeout triggered after ${timeout}ms并中断该请求integration.ts最终以Request timeout after ${timeout}ms的形式把错误抛给调用方。统一把默认超时窗口拉长到 10 秒量级后结合错误日志中带有的请求 ID[CustomFetch:${requestId}]与耗时毫秒数可以显著减少弱网下“还没等到响应就被超时掐断”的误报同时保留可观测性以便后续针对慢接口单独调优。说明仓库当前代码展示的是修复后的默认值更早版本的具体数值无提交记录可考本文不臆测。如何在仓库中进一步验证如果你希望基于该仓库复现或深入验证上述结论可按如下路径阅读变更日志本体apps/desktop/changelog/1.7.0.md其姊妹版本next.md记录了后续待发布内容可对照看修复是否延续Cookie 管理核心apps/desktop/layer/main/src/lib/auth-cookies.ts 及其测试 auth-cookies.test.ts认证服务与会话同步apps/desktop/layer/main/src/ipc/services/auth.ts、cli-session-sync.ts更新决策与 OTAapps/desktop/layer/main/src/updater/index.ts、api.ts、configs.ts以及对应单测index.test.ts、api.test.ts渲染层桥接extension-expose-provider.tsxrefreshSession与rsshubRoute的映射OTA 服务端协议实现位于 apps/ota供对照/manifest、/policy的服务端语义。小结Folo Desktop v1.7.0 表面上是常规 bugfix 版本实质上集中解决了两大类工程问题登录态的“单一事实来源”Cookie 去重、写入清理、更新后刷新与 CLI 同步与更新分发决策的准确性直连 / 渲染层热更 / 商店分发的分流以及 OTAruntimeVersion与商店审核状态的匹配。这些改动全部集中在 Electron 主进程体现了多端客户端对“会话可信度”的强约束宁可写入前先清理、写入后再去重也要保证任何时刻发往 API 的 Cookie 头是确定的、唯一的。对需要维护 Electron 服务端认证 OTA 更新的团队而言auth-cookies.ts 与 updater/index.ts 两处实现值得作为同类系统的设计参考。【免费下载链接】follow Folo is the AI RSS Reader项目地址: https://gitcode.com/GitHub_Trending/fol/follow创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表