如何在Shopify中从Theme App Extension访问Custom App API并完成认证?
问题背景
已在Shopify创建Custom App和Theme App Extension(App Block),并配置App Proxy,尝试从App Block的app.js向后端Node.js代码发起第三方API调用时,收到304/302错误,请求被重定向至/api/auth?shop=shopDomain,系统提示请求缺少Authorization请求头。
已执行步骤
- 在Shopify创建Custom App和Theme App Extension(App Block)
- 配置App Proxy
- 尝试从App Block的
app.js向Custom App后端(Node.js)API发起请求
问题现象
- API调用返回302/304状态码
- Custom App终端错误日志:
2023-01-18 13:53:48 | backend | [shopify-app/INFO] Running validateAuthenticatedSession
2023-01-18 13:53:48 | backend | [shopify-app/INFO] Session was not valid. Redirecting to /api/auth?shop=shopDomain | {shop: shopDomain}
2023-01-18 13:53:48 | backend | [shopify-api/ERROR] Missing Authorization header, was the request made with authenticatedFetch? | {isOnline: false}
解决方案
方法1:使用Shopify官方authenticatedFetch工具
Theme App Extension前端可直接借助@shopify/app-bridge-utils包的authenticatedFetch方法,自动处理认证令牌的添加:
- 安装依赖包:
npm install @shopify/app-bridge @shopify/app-bridge-utils
- 在
app.js中初始化App Bridge并发起认证请求:
import { createApp } from '@shopify/app-bridge'; import { authenticatedFetch } from '@shopify/app-bridge-utils'; // 从Shopify全局变量获取店铺信息 const app = createApp({ apiKey: '你的App API密钥', shopOrigin: window.Shopify.shop, }); const fetchWithAuth = authenticatedFetch(app); // 调用后端API fetchWithAuth('/api/你的接口路径', { method: 'GET', }) .then(response => response.json()) .then(data => console.log(data)) .catch(error => console.error(error));
方法2:后端豁免Extension路由的认证检查
如果后端使用Shopify Node.js API的认证中间件,可针对App Proxy对应的路由跳过会话验证,转而通过验证Shopify请求签名确保合法性:
import { Shopify } from '@shopify/shopify-api'; // 假设App Proxy前缀为/apps/你的代理路径 app.use('/apps/你的代理路径', (req, res, next) => { // 验证请求签名 const isValid = Shopify.Webhooks.validateHmac(req, process.env.SHOPIFY_API_SECRET); if (isValid) { next(); } else { res.status(403).send('无效的请求签名'); } }); // 其他路由保留默认认证中间件 app.use(shopify.validateAuthenticatedSession());
方法3:通过App Proxy直接转发第三方API
若后端仅做中转用途,可直接配置App Proxy指向第三方API,由Shopify处理请求转发与签名验证,无需自行处理认证逻辑。
内容的提问来源于stack exchange,提问作者Sridhar

