Spree 6.0 首次运行设置(First-Run Setup):用一次性令牌取代默认管理员密码

发布时间:2026/9/14 2:06:25
Spree 6.0 首次运行设置(First-Run Setup):用一次性令牌取代默认管理员密码 Spree 6.0 首次运行设置First-Run Setup用一次性令牌取代默认管理员密码【免费下载链接】spreeOpen Source eCommerce Platform for B2B, Marketplace, and Enterprise. REST API, TypeScript SDK, and production-ready Next.js storefront. Self-host it. Own your stack. No vendor lock-in. Zero platform fees.项目地址: https://gitcode.com/GitHub_Trending/sp/spree导读Spree 6.0 彻底移除了长期以来内置在种子数据中的默认管理员账号spreeexample.com/spree123改为一套「首次运行设置」first-run setup流程新安装的项目不再带着公开已知的凭据启动而是由安装者在仪表盘的设置页面上创建管理员账号、命名商店并选择国家/语言。本文基于仓库中的 变更记录changeset、完整设计计划 以及对应源码梳理这套流程的设计动机、一次性令牌机制、API 端点、底层配置服务以及 CI/脚本化安装如何通过环境变量继续无人工介入地工作。读完后你将能够独立完成一次安全的首次启动也能在自动化环境中正确传递管理员凭据。为什么取消默认管理员密码在 Spree 6.0 之前任何通过db:seed初始化的新项目都会生成一个公开已知的超级管理员账号spreeexample.com/spree123。这个硬编码凭据被复制在多个代码库中seed、CLI、模板、e2e 脚本意味着每一个全新部署在互联网上都有着一个「众所周知」的入口谁先找到 URL 谁就能接管这台实例。6.0 的关键决策见 设计计划是种子不再铸造任何管理员账号除非显式提供ADMIN_EMAIL与ADMIN_PASSWORD环境变量无凭据时种子生成一个一次性 setup token并打印一条唯一的设置链接仪表盘在「零管理员」状态下显示设置页面而非登录页凭令牌一次性创建管理员账号并命名商店设置完成、token 消费后该流程永久失效404。对应到 create-spree-app 的变更记录 中具体体现为三点脚手架摘要与生成的 README 不再打印邮箱和密码而是指向 first-run setup首次启动打开设置链接在那里创建管理员账号并命名商店导出的DEFAULT_ADMIN_EMAIL/DEFAULT_ADMIN_PASSWORD常量被彻底删除。一次性 Setup Token 机制token 的载体是Spree::Store模型上的has_secure_token :setup_token在种子创建默认商店时自动生成种子源码Seeds::AdminUser中如果商店的setup_token为空还会补生成因此重复执行db:seed会打印同一条 URL。关键设计点明文存储与邀请 token 同一姿态只在数据库里只有种子数据时有意义设置完成后立即清空setup_token列唯一使用一旦首个管理员存在管理员数量不再为零token 与整个设置端点同时失效且永久失效重新打印bin/rails spree:setup:token可随时重新打印当前设置链接ROTATE1则签发新 tokenURL 拼接Store#setup_url基于Spree::Stores::DashboardUrl解析仪表盘地址——优先使用环境变量配置的dashboard_urlSPREE_DASHBOARD_URL否则回退到已废弃的admin_url再回退到本应用挂载的/dashboardspree_dashboard已安装且有构建产物时开发环境走 Vite dev server最后兜底是商店自身 URL。这一层解析解决了鸡生蛋问题设置链接由db:seed打印而 seed 运行时仪表盘可能尚未启动容器内尤其如此。设置 API 端点设置端点挂在/api/v3/admin/auth/之下与刷新 Cookie 路径/auth/refresh匹配与邀请接受的形态一致三个端点均未认证、与登录共用限流预算控制器源码SetupController。GET /api/v3/admin/auth/setup返回{ setup_required: true | false }。仅在管理员数量为零时为true。该端点安全暴露泄漏的只是一个布尔值且该状态对新安装是自明的。登录页会轮询它以便在「先打开了 /login」的路径上提示去/setup。POST /api/v3/admin/auth/setup请求体参数必填说明setup_token是种子打印的一次性令牌email/password是管理员账号凭据password_confirmation否确认密码first_name/last_name否管理员姓名store_name否重命名种子商店的名字仪表盘表单要求但端点本身不强制country_code是6.0 起ISO 3166-1 alpha-2如CH、DE、USlocale否商店语言缺省从国家派生currency否ISO 4217 代码缺省取国家的默认货币守卫顺序源码见 SetupController#create管理员数量必须为零提交的 token 与商店的setup_token用secure_compare恒时比较country_code必须能解析为真实国家——校验发生在 token 被消费之前设置是一次性的国家填错将无法在带内纠正解析失败返回 422currency若提交了无法解析的代码同样在 token 消费前返回 422可留空表示使用国家货币。并发安全token 一次性意味着不能做裸的 check-then-act——两个携带同一 token 的并发请求可能都通过校验、各创建一个管理员。因此校验在商店行锁store.with_lock内重做锁内store.reload后再次调用setup_token_usable?失败方看到的是已被消费的 token源码 L55-L64。成功时在一个事务内完成创建管理员、以admin角色加入默认商店add_user、按需重命名商店、执行Spree::Stores::ProvisionDefaults下文详解、清空setup_token列随后像InvitationAcceptancesController一样签发刷新 Cookie 与 JWT 并返回管理员 payload。此后任何对该端点的调用都返回 404——token 不匹配、token 已消费、已设置完成三种情况统一渲染 404不泄漏具体原因render_setup_unavailable。GET /api/v3/admin/auth/setup/countries返回{ countries: [{ code, name, currency, locales }] }即 countries gem 已知的每个国家的代码、名称、派生货币ISO 4217与官方语言列表可能为空全部由服务端计算。它存在的原因是设置页面运行在任何凭据之前、无法使用需要认证的 countries 端点同时在客户端推导货币会形成与服务器构建市场时不一致的第二个事实来源。守卫与设置端点一致共享登录限流、管理员存在后 404。国家感知的设置表单与 ProvisionDefaults 服务6.02026-08-15 起的设置表单是「国家感知」的国家下拉框必填数据来自auth/setup/countries语言选择器只列出所选国家的官方语言中 Spree 有翻译的那些外加英语英语默认选中货币选择器以国家自己的货币打头并预选。选择国家会重新派生语言与货币二者保持可编辑——从华沙发货、用欧元定价是完全正常的场景。提交后由 ProvisionDefaults 服务 在一个事务内创建所有「形状依赖国家/货币」的商店默认项引导市场bootstrap marketcountry_codes [country]、name country.name、currency由国家的默认货币派生、default_locale locale原地更新而非新建第二个市场默认库存位置仓库country_code设为所选国家默认开启、first_party不会误吸收同名的卖家位置配送区域Domestic本国Standard固定费率 5以派生货币计价与 International其他国家International Shipping固定费率 20属于商店的默认配送档案重跑时按身份 find-or-create 并同步成员国家列表避免残留旧国家的行包裹类型package type按商店的公制/英制偏好创建默认纸箱30×23×10 cm 或 12×9×4 intare 重量按商店重量单位换算已有默认箱则不覆盖门店自提pickup默认仓库开启pickup_enabled创建Store Pickup配送方法计算器为 0 金额、以派生货币计价重述种子计算器货币数字交付等方法在知道国家之前已以当时的货币种子化很可能默认美元服务会把已种子的零金额费率统一改写为派生货币——只改写零金额的种子默认商家自己定价的方法绝不动。服务的call(store:, country:, locale:, currency:)签名中locale缺省时优先取国家自己的语言若 Spree 有对应翻译否则英文currency缺省取国家默认货币解析失败静默回退调用方先校验种子读错环境变量不应让安装失败。服务有且仅有两个调用方设置端点在商店锁内与Seeds::AdminUser的环境变量分支——它绝不能被接到设置页面或管理动作上因为对已配置商店重跑它无异于一次数据重置。CLI 与脚手架的行为变化create-spree-app脚手架摘要与生成的 README 不再打印邮箱/密码首次启动直接打开设置链接.changeset/create-spree-app-first-run-setup.md。spree/cli见 CLI 变更记录 与 init 命令源码spree init交互式询问管理员邮箱与密码或接受--admin-email/--admin-password两者都在 Docker 启动之前完成校验只传其中一个会被拒绝非交互运行CI、管道调用且未传标志时不创建任何管理员种子打印一次性设置链接摘要卡片展示它--open直接打开该路径会跳过样例数据导入需要管理员归属设置完成后可用spree sample-data补载spree dev使用spree init时种子的管理员邮箱若未种子任何账号则指向设置链接而不是猜测地址依赖旧凭据的脚本化安装必须显式传入--admin-email/--admin-password。种子与脚本化安装的兼容路径Seeds::AdminUser的行为现在完全由环境决定仅当ADMIN_EMAIL且ADMIN_PASSWORD同时存在时才创建管理员可选ADMIN_FIRST_NAME/ADMIN_LAST_NAME并把用户加入默认商店环境变量分支还会调用ProvisionDefaults国家/语言/货币分别由STORE_COUNTRYISO 3166-1 alpha-2默认US、STORE_LOCALE默认en、STORE_CURRENCY提供——CI、worktree 与 e2e 因此可以保持完全字节级一致的输出同时脚本化的非美区安装无需仪表盘也能得到正确的配送区域两个变量都缺失时Seeds::AdminUser只打印设置 URL仅输出到 stdout避免进入日志聚合器Rails.logger只记提示不落 token 本身。裸db:seed无凭据的净效果是商店带市场、税类、产品类型、数字交付、角色与 API key但没有仓库、配送区域和自提方法——直到设置完成。这是刻意为之还没有人说过店铺开在哪里。配套的spree:cli:create_adminrake 任务改为按邮箱 find-or-create幂等并且在缺少admin角色时大声失败而不是静默铸造一个无角色用户。安全要点与迁移提示零管理员门禁 一次性令牌双重守卫仅靠「管理员数量为零」的门禁是不够的——它会让刚部署的实例被第一个找到 URL 的人认领token 把认领权交到持有安装输出的人手里令牌只存活于种子数据期明文存储可接受因为一旦管理员存在、token 清空端点即 404流程死亡显式传凭据的安装则根本不会进入该流程恒时比较token 校验使用ActiveSupport::SecurityUtils.secure_compare且统一 404 不区分失败原因避免侧信道与信息泄漏迁移行动项凡依赖旧spreeexample.com/spree123的脚本、CI 流水线与模板升级到 6.0 时必须显式传入ADMIN_EMAIL/ADMIN_PASSWORD或 CLI 的--admin-email/--admin-password否则将不会得到管理员账号只会看到设置链接。延伸阅读完整设计计划Store Context First-Run Setup——包含 store contextX-Spree-Store-Id头、publishable key 选店等配套改造SetupController 源码——三个端点的完整实现Seeds::AdminUser 源码——种子与环境变量分支ProvisionDefaults 服务源码——国家感知默认项的一次性装配CLI init 命令源码——交互式与非交互式安装路径CLI 变更记录 与 create-spree-app 变更记录——本次变更的发布说明。【免费下载链接】spreeOpen Source eCommerce Platform for B2B, Marketplace, and Enterprise. REST API, TypeScript SDK, and production-ready Next.js storefront. Self-host it. Own your stack. No vendor lock-in. Zero platform fees.项目地址: https://gitcode.com/GitHub_Trending/sp/spree创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

关于本文作者

来自尧图内容编辑团队

尧图内容编辑团队 内容团队

尧图内容编辑团队

本文由尧图网络内容编辑团队执笔。团队由资深项目经理、前端工程师与设计师组成,所有内容均来自亲手交付的真实项目,先讲清问题、再给出可落地的解法。尧图深耕北京网站建设十年,服务过京华建材集团、智造科技等各行业客户,把一线经验沉淀为可复用的行业观察。

  • 十年建站经验,覆盖建材、制造、服务、文创等
  • 项目经理把关选题与事实准确性
  • 工程师与设计师联合撰写专业细节
  • 统一编辑规范,保证文风与排版一致
  • 每月复盘转化数据,迭代选题方向

延伸阅读

相关资讯与近期热门内容

深度阅读推荐

建站决策前值得细读的三篇

网站改版的5个关键决策
2024-08-12

网站改版的5个关键决策

什么时候该改版、改到什么程度、如何避免流量掉光,京华建材集团改版复盘给出答案。

获取专属建站方案

看完文章,把您的行业与预算告诉我们,免费获取一份量身定制的官网建设方案与报价。

立即免费咨询