如何在现有Shopify产品查询代码中添加获取Access Token与scopes的逻辑?
问题
现有一段基于axios和dotenv的Node.js代码,已能成功获取Shopify店铺的产品数据:
const axios = require('axios'); require('dotenv').config(); // Shopify Store의 정보 const API_KEY = process.env.SHOPIFY_API_KEY; const API_PASSWORD = process.env.SHOPIFY_API_SECRET; const STORE_URL = process.env.SHOPIFY_STORE_URL; // Shopify API를 통해 제품 목록 가져오기 async function getProductList() { try { const url = `${STORE_URL}/admin/api/2023-04/products.json`; const response = await axios.get(url, { auth: { username: API_KEY, password: API_PASSWORD } }); const products = response.data.products; for (const product of products) { console.log(product.title); } } catch (error) { console.error('Error:', error); } } // 제품 목록 가져오기 getProductList();
现需在该代码基础上添加逻辑以获取Access Token和scopes,请问需要补充哪些内容?
解决方案
要获取Access Token和授权范围(scopes),需补充以下几部分逻辑:
1. 新增环境变量配置
在.env文件中添加Shopify应用的重定向URI(需提前在Shopify后台的应用设置中配置完成):
SHOPIFY_REDIRECT_URI=http://localhost:3000/callback
2. 添加生成授权URL的逻辑
通过Shopify的OAuth2授权流程生成授权链接,引导店铺管理员完成授权,这是获取Access Token的前置步骤:
function getAuthorizationUrl() { // 根据业务需求设置所需权限,多个权限用逗号分隔 const scopes = 'read_products,write_products'; return `${STORE_URL}/admin/oauth/authorize?client_id=${API_KEY}&scope=${scopes}&redirect_uri=${encodeURIComponent(process.env.SHOPIFY_REDIRECT_URI)}`; }
3. 添加回调处理逻辑(兑换Access Token与获取Scopes)
管理员授权后,Shopify会重定向到你配置的SHOPIFY_REDIRECT_URI,并携带授权码(code参数)。通过该授权码即可兑换Access Token,同时获取已授权的scopes:
async function getAccessToken(code) { try { const response = await axios.post(`${STORE_URL}/admin/oauth/access_token`, { client_id: API_KEY, client_secret: API_PASSWORD, code: code }); // 提取返回的Access Token和授权范围 const { access_token, scope } = response.data; console.log('Access Token:', access_token); console.log('已授权范围:', scope); return { access_token, scope }; } catch (error) { console.error('获取Access Token失败:', error); throw error; } }
4. 整合完整流程(含本地测试服务器)
如果是本地测试,可添加一个简易HTTP服务器处理回调请求,完整代码如下:
const axios = require('axios'); require('dotenv').config(); const http = require('http'); const url = require('url'); // Shopify 配置信息 const API_KEY = process.env.SHOPIFY_API_KEY; const API_PASSWORD = process.env.SHOPIFY_API_SECRET; const STORE_URL = process.env.SHOPIFY_STORE_URL; const REDIRECT_URI = process.env.SHOPIFY_REDIRECT_URI; // 生成授权URL function getAuthorizationUrl() { const scopes = 'read_products,write_products'; // 按需调整权限 return `${STORE_URL}/admin/oauth/authorize?client_id=${API_KEY}&scope=${scopes}&redirect_uri=${encodeURIComponent(REDIRECT_URI)}`; } // 通过授权码兑换Access Token和Scopes async function getAccessToken(code) { try { const response = await axios.post(`${STORE_URL}/admin/oauth/access_token`, { client_id: API_KEY, client_secret: API_PASSWORD, code: code }); return response.data; } catch (error) { console.error('获取Access Token失败:', error); throw error; } } // 修改原有产品列表获取函数,改用Access Token验证 async function getProductList(accessToken) { try { const url = `${STORE_URL}/admin/api/2023-04/products.json`; const response = await axios.get(url, { headers: { 'X-Shopify-Access-Token': accessToken } }); const products = response.data.products; products.forEach(product => { console.log(product.title); }); return products; } catch (error) { console.error('获取产品列表失败:', error); } } // 创建简易HTTP服务器处理授权流程 const server = http.createServer(async (req, res) => { const parsedUrl = url.parse(req.url, true); // 首页返回授权链接 if (parsedUrl.pathname === '/') { const authUrl = getAuthorizationUrl(); res.writeHead(200, { 'Content-Type': 'text/html' }); res.end(`<a href="${authUrl}">点击授权Shopify店铺</a>`); } // 处理授权回调 else if (parsedUrl.pathname === '/callback') { const code = parsedUrl.query.code; if (!code) { res.writeHead(400, { 'Content-Type': 'text/plain' }); res.end('缺少授权码'); return; } try { const { access_token, scope } = await getAccessToken(code); res.writeHead(200, { 'Content-Type': 'text/plain' }); res.end(`Access Token: ${access_token}\n授权范围: ${scope}\n\n授权成功,已开始获取产品列表...`); // 授权成功后调用产品列表接口 await getProductList(access_token); } catch (error) { res.writeHead(500, { 'Content-Type': 'text/plain' }); res.end('授权失败,请重试'); } } // 404页面 else { res.writeHead(404, { 'Content-Type': 'text/plain' }); res.end('页面不存在'); } }); // 启动服务器 const PORT = 3000; server.listen(PORT, () => { console.log(`服务器运行在 http://localhost:${PORT}`); });
重要说明
- 权限范围(scopes)需根据实际业务需求选择,比如
read_products为只读产品权限,write_products为可修改产品权限 - 原有代码采用的是私有应用的API密钥+密码验证方式,而获取Access Token属于公开应用的OAuth2授权流程,修改后的代码兼容使用Access Token调用Shopify接口
- 测试前需确保
.env文件中的所有配置项正确,且SHOPIFY_REDIRECT_URI已在Shopify后台的应用设置中添加为有效重定向地址
内容的提问来源于stack exchange,提问作者Honggaenugget1510
相关产品推荐
相关产品推荐

