资讯详情

资讯详情

Spree Admin SDK 首次运行设置:以国家驱动商店初始化,认证方法直接返回会话

Spree Admin SDK 首次运行设置以国家驱动商店初始化认证方法直接返回会话【免费下载链接】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/admin-sdk的一次 major 变更首次运行设置first-run setup现在要求明确商店销售国completeSetup以country_code为必填、可选locale与currency并默认取该国自身的语言与货币同时新增无凭证的auth.setupCountries()国家清单接口且login、acceptInvitation、resetPassword、completeSetup四个认证方法直接以所建立的会话JWT 用户信息resolve调用方无需再等待 provider 状态。读完本文你将掌握 Admin SDK 首次运行设置的完整调用链、参数语义、后端实现与错误处理细节。变更速览该变更记录于 .changeset/admin-sdk-setup-country.md对spree/admin-sdk标记为 major 版本升级核心包含三点首次运行设置询问商店销售国completeSetup现在要求country_code并接受可选的locale与currency后两者默认取该国的首选官方语言与本国货币保证商店的货币与地理默认一致。货币校验收紧无法识别的货币代码会被直接拒绝422而不再被静默忽略。会话即返回值dashboard 认证上下文上的login、acceptInvitation、resetPassword、completeSetup均以它们建立的会话 resolve调用方可以直接读取已登录用户无需等待 provider 状态更新。此外新增公开的auth.setupCountries()列出商店可用于设置的每个国家及其派生货币与官方语言与首次运行流程的其他部分一样它不需要任何凭证且一旦存在管理员账号就停止响应404。首次运行设置的整体流程首次运行设置是 Spree 安装后的一次性引导在没有管理员用户时用它创建第一个管理员账号并接管adopt种子数据中已存在的默认商店。三个端点全部挂在/api/v3/admin/auth/...之下这样签发的 refresh-token cookie 的 path 与/auth/refresh一致且都是未认证的——因为流程本身发生在任何凭证存在之前。路由定义见 spree/api/config/routes.rbget auth/setup, to: setup#show # 检查是否仍需要设置 get auth/setup/countries, to: setup#countries # 列出可设置的国家 post auth/setup, to: setup#create # 完成设置在 Admin SDK 中对应的方法位于client.auth命名空间实现见 packages/admin-sdk/src/admin-client.tsSDK 方法HTTP 调用说明auth.setupStatus()GET /auth/setup返回{ setup_required: boolean }仅当安装中不存在任何管理员用户时为true登录页用它决定是否展示设置界面auth.setupCountries()GET /auth/setup/countries列出可用于设置的国家及派生货币/语言无需凭证auth.completeSetup(params)POST /auth/setup创建首个管理员账号并接管默认商店凭一次性 setup token 授权一个值得注意的实现细节Admin SDK 的请求层对所有/auth/前缀的端点不附加X-Spree-Store-Id头。原因在 packages/admin-sdk/src/client.ts 的注释中写得很清楚——认证端点在设计上就是与商店无关的登录、刷新、设置、邀请接受都发生在选择商店之前或之间一个来自旧会话的过期 store id 绝不能让回来的路 404。completeSetupcountry_code 成为必填completeSetup的请求体类型为SetupParams完整定义见 packages/admin-sdk/src/params.tsexport interface SetupParams { setup_token: string // 安装时打印的一次性 token唯一凭证 email: string // 首个管理员邮箱 password: string password_confirmation?: string first_name?: string last_name?: string store_name?: string // 可选不传则保留种子商店的原名 /** * ISO 3166-1 alpha-2 国家码如 US。必填 * 它决定默认市场、仓库、配送区域以及商店货币。 */ country_code: string /** 店面 locale默认取该国的语言 */ locale?: string /** ISO 4217 货币如 EUR。默认取该国货币——仅在商店用其他货币定价时传入 */ currency?: string }默认值语义货币与地理天然一致locale与currency均是可选的缺省时从country_code派生locale默认取该国首选官方语言currency默认取该国的法定货币。这样设计的目的在控制器注释spree/api/app/controllers/spree/api/v3/admin/setup_controller.rb里说得很直白市场market在设置时构建的形态与展示给商家的货币两者不可能不一致——货币与地理在源头就被绑定了。只有当你确实需要用不同于销售国的货币定价时才显式传currency。未知货币拒绝而非静默忽略新语义中一个无法解析的货币代码会以 422 拒绝而不是像旧行为那样被悄悄丢弃。后端通过 unknown_currency? 判断def unknown_currency? params[:currency].present? ::Money::Currency.find(params[:currency].to_s.strip).nil? end命中后返回render_unknown_currency422 validation_error错误码。为什么如此严格控制器注释给了关键理由setup token 在同一请求中被消耗one-shot如果设置完成后才发现币种是错的将没有带内手段修正——因为流程在第一个管理员创建后即永久关闭。同理缺失或无法识别的country_code也会返回 422render_missing_country错误信息会区分未传与传了但未知两种情况。一个完整的设置调用示例import { createAdminClient } from spree/admin-sdk const client createAdminClient({ baseUrl: https://your-store.com, // 首次运行设置不需要 secretKey / jwtToken——流程本身无凭证 }) // 1. 检查是否仍需要设置 const { setup_required } await client.auth.setupStatus() // 2. 拉取可选国家拿到该国派生的货币与语言 const { countries } await client.auth.setupCountries() // [{ code: CH, name: Switzerland, currency: CHF, locales: [de,fr,it,rm] }, ...] // 3. 完成设置只给 country_codelocale/currency 自动取瑞士默认 const session await client.auth.completeSetup({ setup_token: token-printed-at-install-time, email: ownerexample.com, password: Secret123!, password_confirmation: Secret123!, first_name: Olivia, last_name: Owner, store_name: My Store, country_code: CH, // locale: de, // 不传默认取国家语言 // currency: CHF // 不传默认取国家货币 }) // session.token / session.user 即刻可用见下文会话即返回值auth.setupCountries无凭证的国家清单auth.setupCountries()是本次变更新增的公开接口返回SetupCountries类型定义见 packages/admin-sdk/src/params.tsexport interface SetupCountry { /** ISO 3166-1 alpha-2 国家码如 CH */ code: string name: string /** 选择该国后商店获得的 ISO 4217 货币如 CHF可能为 null */ currency: string | null /** 官方语言列表如 [de, fr, it, rm] */ locales: string[] } export interface SetupCountries { countries: SetupCountry[] }它的定位见 admin-client.ts 的 JSDoc无需凭证设置界面运行在任何凭证存在之前因此不能用需要认证的国家列表端点货币与语言由服务端派生而非客户端自行推导保证设置构建的市场与展示给商家的货币不可能矛盾一旦存在任何管理员用户即返回 404与整个设置流程一样永久关闭。集成测试 spree/api/spec/integration/spree/api/v3/admin/setup_spec.rb 直接验证了瑞士这一典型案例switzerland data[countries].find { |country| country[code] CH } expect(switzerland[currency]).to eq(CHF) expect(switzerland[locales]).to include(de)语言清单的过滤逻辑locales并非机械地返回国家所有官方语言而是经过 offerable_locales 过滤取国家官方语言与 Spree 已翻译 locale 的交集。理由同样写在注释里——瑞士官方语言包含罗曼什语Romansh而 Spree 并没有对应翻译把一个背后没有内容的语言提供给店面是没有意义的若某国所有官方语言都没有翻译包则退化为[en]。同时未安装spree_i18n的安装只认识英语此时直接返回完整官方语言列表反而更合理商家的母语仍是其店面的正确默认无论本安装是否携带该语言的翻译包。会话即返回值四个认证方法直接 resolve 会话变更的另一半是dashboard auth 上下文上的login、acceptInvitation、resetPassword、completeSetup现在都以它们建立的会话 resolve。在 Admin SDK 层这四个方法的返回类型全部是AuthTokens定义见 admin-client.tsexport interface AuthTokens { /** 短期 JWT access token放入 Authorization: Bearer仅存内存 */ token: string user: AdminUser }也就是说调用方可以在一次await之后直接读取user而不必等待 provider 状态如 React Context 的异步更新再拿用户信息。以resetPassword为例官方示例见 packages/admin-sdk/examples/auth/reset-password.ts// token 来自邮件链接的 ?token 参数。成功后管理员即已登录 // JWT 返回给调用方refresh token 以 HttpOnly cookie 设置。 const auth await client.auth.resetPassword(reset-token-from-email, { password: new-password-123, password_confirmation: new-password-123, }) // auth.token / auth.user 直接可用四个方法对应的后端行为保持一致loginPOST /auth/login、acceptInvitationPOST /auth/invitations/:id/accept、completeSetupPOST /auth/setup、resetPasswordPATCH /auth/password_resets/:token在成功时都签发 JWT refresh-token cookiecookie 的 path 都落在/api/v3/admin/auth之下从而与/auth/refresh共享路径。acceptInvitation的请求体见InvitationAcceptParamsparams.ts已有账号可传空体新账号则在接受时携带password及可选的确认密码与姓名。后端实现SetupController 与 ProvisionDefaults理解前端 API 之后值得看一下后端的落地实现它解释了为什么这些接口是一次性且带防护的。控制器与防护措施SetupController 实现了show/countries/create三个动作关键设计限流三个动作都套用rate_limit_login/rate_limit_window限流与登录共用配置。token 即凭证setup_token_usable? 用ActiveSupport::SecurityUtils.secure_compare做常量时间比较避免时序侧信道。防并发消耗token 是一次性的因此先检查再行动是不够的——两个携带同一 token 的并发请求可能都通过检查并各自创建管理员。控制器在store.with_lock行锁内重新校验 token输家会看到已消耗的 tokenL59-L64。统一 404 语义render_setup_unavailable 对token 不匹配 / token 已消耗 / 已完成设置三种情况返回同样的 404避免端点泄露任何信息。ProvisionDefaultscountry_code 的下游影响completeSetup中最具业务分量的动作是调用Spree::Stores::ProvisionDefaultsspree/core/app/services/spree/stores/provision_defaults.rb。这个服务把country_code变成一整套商店默认配置在单个事务内完成产物说明默认市场更新商店的default_country_code/default_currency/default_locale并同步默认市场market的名称、货币、语言与国家集合仓库创建/接管默认发货仓库stock location绑定国家码若国家改变则清空原地址字段配送区域按 Shopify 风格创建 Domestic国内$5与 International国际$20两个区域及其平价运费方法货币用解析后的currency包装类型按商店公制/英制单位创建默认纸箱含尺寸与皮重皮重影响计费重量报价门店自提默认仓库开启 pickup创建 0 元自提配送方法修正种子计算器将种子阶段国家未知时创建的数字商品配送方法的默认货币重述为解析后的货币避免从苏黎世发货却用美元报价注释特别强调这个服务只允许从首次运行设置端点与 env-credential 分支的种子逻辑调用绝不可接到设置页面上——对已配置的商店运行它相当于一次数据重置L9-L12。此外adopt_default_storesetup_controller.rb#L181-L191会清空setup_token、把首个管理员加入商店并允许不重命名商店store_name可选。错误处理与边界情况汇总场景HTTP 状态说明已完成设置后再次调用 setup 系端点404流程永久关闭Setup is not availabletoken 缺失 / 不匹配 / 已消耗404与已完成设置返回一致防信息泄露country_code缺失422Country cant be blankcountry_code未知422Unknown country XXcurrency无法识别422Unknown currency XXX——token 一次性宁可拒绝不可静默忽略邮箱/密码等校验失败422ActiveRecord::RecordInvalid转为校验错误响应测试验证本次行为的契约由集成测试锁定spree/api/spec/integration/spree/api/v3/admin/setup_spec.rbGET /api/v3/admin/auth/setup返回setup_required: truePOST /api/v3/admin/auth/setup成功后响应包含token且user.email与提交值一致携带错误 token 时返回 404GET /api/v3/admin/auth/setup/countries中瑞士返回CHF与包含de的语言列表。升级注意事项由于该变更对spree/admin-sdk是 major 版本升级时请关注completeSetup调用必须补country_code否则请求将 422若此前依赖静默忽略未知货币的行为现在会直接报错——这正是变更意图请在调用前校验货币代码。利用新的返回值login/acceptInvitation/resetPassword/completeSetup的await结果直接含token与user可据此立即渲染用户态简化此前等待 provider 状态的样板代码。setupCountries()只应在setupStatus()表明需要设置时调用且调用方应容忍 404管理员已创建后的正常状态。默认值语义不传locale/currency时商店将采用所选国家的语言与货币若业务上需要在 A 国销售、用 B 货币定价务必显式传currency。整体而言这次变更把商店从哪来、用什么货币、说什么语言收敛到了首次运行设置这一个无凭证、一次性、带 token 防护的流程里并在 SDK 层面提供了类型安全、语义清晰的调用面值得在实现自定义部署引导安装向导、多租户开通、代理商开店时直接复用。【免费下载链接】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),仅供参考
觉得有用,分享给同行:

为您的企业打造数字门面

稳重轻奢商务风格,端正雅致视觉,长效耐看不易过时。

立即咨询 →