[控场AI]
· 7 分钟阅读· 3,904 字

从本地到生产:React SPA + AuthKit 部署实战

从本地到生产:React SPA + AuthKit 部署实战

Vite + React SPA 借助 AuthKit 上线生产时,以 httpOnly cookie、自定义认证域名与服务端强制校验构建清晰的认证责任边界。

文章以 WorkOS 的指南为脉络,梳理了 Vite 构建的 React SPA 从本地迁移到生产域名时常遇到的认证陷阱。核心症结集中在三处:cookie 作用域与 SameSite 策略在跨域场景下失效、refresh token 存放在前端易被 XSS 窃取、API 层缺少对每个请求的强制校验。对应的方案是让 refresh token 走 httpOnly cookie,前端只持有短生命周期的 access token,并把认证 API 绑定到自有域名以简化 cookie 与 CSP 配置。同时,预览环境也需接入认证,Node API 则对每次请求独立校验 access token,形成浏览器、前端、服务端三层各司其职、无单点承担全部信任的架构。

将 Vite 构建的 React 单页应用部署到生产环境,远不是 npm run dev 之后按下发布键那么简单。认证环节尤其容易在从 localhost 迁移到真实域名时出现 cookie 失效、跨域拦截、刷新令牌丢失等连锁问题。WorkOS 官方发布的一篇技术指南《Ship a React SPA with AuthKit to production》,以一套可复现的路径拆解了 Vite + React 应用借助 AuthKit 上线时涉及的几个关键工程决策。本文将结合该指南的核心脉络,提炼其中的实践要点与设计取舍。

rss source: Ship a React SPA with AuthKit to production

为什么本地能跑、上线就断

很多团队在开发阶段用 AuthKit 调试一切正常,切换到生产域名后却出现「登录成功但刷新即掉线」的现象。根因通常集中在三处:

  • Cookie 作用域与 SameSite 策略不匹配。本地 localhost 下宽松的 cookie 设置在生产跨子域或跨顶级域时会被浏览器拒绝。
  • 令牌存储方式过于信任前端。若把 refresh token 放在 localStorage,XSS 一旦发生就等同于账号泄露。
  • API 层缺少对每个请求的强制校验。前端路由守卫只是体验层,真正的安全边界必须落在服务端。

该指南的应对思路是:refresh token 走 httpOnly cookie,前端只持有短生命周期的 access token,并在 Node API 侧对每次请求做验证。

SameSite 属性是浏览器用于防御 CSRF 的 cookie 控制字段,取值主要有 Strict、Lax、None 三种。Strict 下 cookie 仅在完全同站请求中发送,跨站请求一律不带;Lax 是当前浏览器的默认值,允许顶级导航的 GET 请求携带 cookie,但 POST 等跨站子请求不带;None 则要求同时设置 Secure,允许跨站发送。本地 localhost 调试时,前端与 API 常在同一端口或通过开发代理同源访问,cookie 不受 SameSite 限制;一旦上线后前端域名与认证域名分属不同站点,若 SameSite 未正确设为 None; Secure,浏览器就会静默丢弃 cookie,表现为「登录成功但刷新即掉线」。此外 cookie 的 Domain 与 Path 也决定了它能否被目标请求携带,生产域名切换后若沿用旧的默认作用域,同样会导致凭证无法送达。

指南明确采用 httpOnly cookie 承载 refresh token 的方案。这一选择带来两个直接收益:JavaScript 无法读取该 cookie,XSS 攻击难以直接窃取长期凭证;同时前端不需要自行管理刷新逻辑中的凭证持久化。

需要注意的是,httpOnly cookie 对部署配置提出了额外要求。生产域名必须启用 HTTPS,cookie 需设置 Secure、SameSite 属性,并按实际部署结构决定是否使用 Domain 共享。如果前端与认证 API 分属不同站点,还需要处理跨站 cookie 的第三方场景限制。指南建议通过自定义 Authentication API 域名的形式,把认证端点收敛到可控的域名下,从而让 cookie 的作用域与调用关系保持一致,减少浏览器策略带来的不确定性。

前端侧的刷新流程因此变得清晰:access token 过期时,调用认证端点触发 cookie 携带的 refresh 流程,拿到新的 access token 后重试原请求。整个过程对用户透明。

httpOnly cookie 是服务端通过 Set-Cookie 响应头中的 HttpOnly 标记写入的浏览器存储单元,其核心特征是任何 JavaScript(包括 document.cookie 与 Fetch/XHR)都无法读取或修改,只能由浏览器在匹配的请求中自动携带。这一特性使其成为承载 refresh token 的理想载体:即便页面存在 XSS 漏洞,攻击者也无法直接读取长期凭证。但它并非万能,仍需配合 Secure(仅 HTTPS 传输)、SameSite(防 CSRF)以及合理的过期时间共同使用。同时由于前端无法读取,刷新逻辑必须完全依赖服务端通过 cookie 识别身份,前端只负责在 access token 失效时发起刷新请求,并接收返回的新 access token。这种「前端不可见、后端可验证」的分工,是当前 SPA 认证中较为稳妥的凭证管理模式。

用自定义 Authentication API 域名收敛边界

AuthKit 默认提供托管域名,但指南推荐把认证 API 绑定到自有域名。这一动作的价值不只在品牌一致性:

  • Cookie 作用域可控。自定义域名让 cookie 的 Domain 属性明确,避免依赖托管域带来的跨域复杂度。
  • CSP 与网络策略简化。企业环境中的内容安全策略往往对第三方域名有限制,自有域名更容易纳入白名单。
  • 调试链路更短。开发者工具中看到的请求域名与实际业务域名一致,排查跨域问题的成本显著下降。

这一部分体现的是一种普遍的工程原则:把认证这种安全敏感的基础设施尽可能放在自己可观测、可配置的边界内。

CSP(Content Security Policy,内容安全策略) 是一组通过 HTTP 响应头或 meta 标签下发的浏览器安全规则,用于限定页面可以加载和请求哪些来源。企业环境中的 CSP 通常配置得较为严格,只允许白名单内的域名参与脚本、样式、连接等行为。若认证端点使用第三方托管域名,团队必须将其显式加入 connect-src 与 frame-src 等指令,否则请求会被浏览器直接拦截,且报错信息往往指向跨域而非 CSP,排查成本较高。将认证 API 绑定到自有域名后,CSP 白名单可以与企业其他内部域名统一管理,既减少了逐个放行第三方的维护负担,也降低了因供应商域名变更导致策略失效的风险。这一做法与「基础设施尽量自持」的工程思路一致。

Preview 部署与 Node API 的请求校验

现代前端工作流普遍使用预览部署(preview deployments)来验证 PR。指南指出,预览环境同样需要接入认证,否则无法真实模拟登录态下的行为。这要求预览域名也被纳入 AuthKit 的回调地址与 cookie 策略中,避免「预览能打开但登不进去」的割裂体验。

后端方面,指南给出的核心约束是:Node API 对每一个请求都进行验证。这意味着不能只依赖前端路由拦截,也不能假设内网调用可信。每个请求携带的 access token 都需要在服务端校验签名与有效期,失败则返回 401。这种「默认不信任」的模型,是前后端分离架构下保护数据接口的基本前提。

从整体架构看,这条路径把安全责任清晰地划分:浏览器负责安全地持有与自动携带 httpOnly cookie,前端负责在 access token 失效时触发刷新,Node API 负责对每次访问做最终裁决。三层各司其职,没有单点承担全部信任。

Access token 与 refresh token 的分工是理解整套方案的关键。Access token 是短期凭证,通常为 JWT 格式,携带用户身份与权限声明,由前端在每次 API 请求的 Authorization 头中发送,服务端通过校验签名与 exp 过期时间来判断其有效性;由于它暴露在前端内存中,生命周期被刻意设得很短(数分钟到一小时)以缩小泄露窗口。Refresh token 则是长期凭证,仅用于向认证端点换取新的 access token,本身不参与业务请求。当 access token 过期时,前端触发刷新流程,浏览器自动携带 httpOnly cookie 中的 refresh token,服务端验证后签发新的 access token。服务端对每个请求独立校验 access token,意味着即使前端路由守卫被绕过,数据接口仍会返回 401,从而保证安全边界始终落在服务端。

落地时的检查清单

将这套方案应用到实际项目时,可以按以下顺序核对:部署域名是否启用 HTTPS 并正确设置 cookie 属性;认证 API 是否绑定到自定义域名并纳入 CSP;预览环境的回调地址是否同步配置;Node API 是否对每个请求执行令牌校验;access token 的生命周期是否足够短以降低泄露窗口。这些检查点覆盖了从本地到生产过程中最常出问题的环节。

原文偏重操作步骤,本文则更关注其中的架构选择。对正在把 React SPA 推向生产、又不希望自建整套认证体系的团队而言,AuthKit 配合 httpOnly cookie 与强制服务端校验的组合,提供了一条责任边界相对清晰的路径。

#React SPA 部署#AuthKit 认证#httpOnly cookie#刷新令牌#自定义认证域名#Node API 请求校验#Vite React 生产部署#预览部署认证
分享:

相关推荐