在Shopify应用Webhook处理器中调用Admin API的最佳授权方式
Shopify Webhook处理器中发起认证Admin API请求的最佳实践
在AWS Lambda(或通过EventBridge接收Webhook)的场景下,处理Shopify订单Webhook时发起Admin API请求,核心是利用**离线会话(Offline Session)**完成认证,以下是具体实现步骤:
关键前提
- 你的Shopify应用在店铺安装时,已经获取并存储了该店铺的离线Access Token(建议存在DynamoDB这类数据库中,Lambda需具备访问权限)
- Lambda环境变量中配置了Shopify应用的
API_KEY、API_SECRET_KEY
实现步骤
1. 从Webhook/EventBridge事件中提取必要信息
每个Shopify Webhook事件(包括EventBridge转发的)都会携带以下关键字段:
shop_domain: 触发Webhook的店铺域名(如your-store.myshopify.com)api_version: Webhook使用的API版本(如2024-07)
2. 创建认证会话
通过@shopify/shopify-api库创建离线会话,无需用户交互,直接用存储的离线Access Token:
- 先从数据库根据
shop_domain查询对应的离线Access Token - 用获取到的token、店铺域名、API版本构建会话对象
3. 完整示例代码
const Shopify = require('@shopify/shopify-api'); // 以AWS SDK v3操作DynamoDB为例 const { DynamoDBClient, GetItemCommand } = require("@aws-sdk/client-dynamodb"); const { unmarshall } = require("@aws-sdk/util-dynamodb"); // 初始化Shopify API客户端 Shopify.Context.initialize({ API_KEY: process.env.SHOPIFY_API_KEY, API_SECRET_KEY: process.env.SHOPIFY_API_SECRET, SCOPES: process.env.SHOPIFY_APP_SCOPES(','), HOST_NAME: process.env.SHOPIFY_APP_HOST, API_VERSION: Shopify.ApiVersion.July24, // 可被Webhook事件中的api_version覆盖 IS_EMBEDDED_APP: false, // 后台Webhook处理无需嵌入式配置 }); // Lambda处理函数 exports.handler = async (event) => { try { // 解析EventBridge/Webhook事件数据(根据实际格式调整) const webhookData = event.detail || event; const { shop_domain, api_version } = webhookData; // 1. 从DynamoDB获取店铺的离线Access Token const ddbClient = new DynamoDBClient({ region: process.env.AWS_REGION }); const getItemCmd = new GetItemCommand({ TableName: 'shopify_store_tokens', Key: { shop_domain: { S: shop_domain } } }); const tokenResult = await ddbClient.send(getItemCmd); const storeData = unmarshall(tokenResult.Item); const offlineAccessToken = storeData.access_token; // 2. 创建离线会话 const session = new Shopify.Session.OfflineSession(shop_domain); session.accessToken = offlineAccessToken; session.apiVersion = api_version || Shopify.ApiVersion.July24; // 3. 执行Admin API请求(以修改商品为例) const product = await Shopify.rest.Product.find({ session, id: '7504536535062' }); product.title = 'A new title'; await product.save({ update: true }); return { statusCode: 200, body: 'Success' }; } catch (error) { console.error('Error processing webhook:', error); return { statusCode: 500, body: 'Error' }; } };
注意事项
- Webhook签名验证:必须在处理请求前验证Webhook签名,防止恶意请求,
@shopify/shopify-api提供的Shopify.Webhooks.verify方法可直接使用 - Token存储:离线Access Token长期有效(除非店铺卸载应用),需安全存储,Lambda禁止硬编码敏感信息
- API版本一致性:尽量使用Webhook事件携带的
api_version发起请求,避免版本不兼容问题
内容的提问来源于stack exchange,提问作者user1148920
相关产品推荐
相关产品推荐

