Node.js对接Amazon SP API:Access Token自动刷新方案问询
实现Amazon SP API Access Token自动刷新方案
可以通过缓存Token并提前刷新的方式解决Token过期问题,核心思路是:
- 缓存当前有效的Access Token及其过期时间
- 每次调用SP API前检查Token是否即将过期,若过期或即将过期则自动刷新
- 封装Token管理逻辑,让业务代码无需关心Token刷新细节
具体实现步骤
1. 封装Token管理模块
创建独立的tokenManager.js模块,负责Token的获取、缓存和刷新:
const axios = require('axios'); const dotenv = require('dotenv'); dotenv.config({ path: './.env' }); // 缓存当前Token信息 let currentToken = null; // 记录Token过期时间戳(提前30秒刷新,避免网络延迟导致过期) let tokenExpiresAt = 0; // 刷新Token的核心方法 const fetchNewToken = async () => { try { const response = await axios.post(process.env.AMZ_ENDPOINT, { grant_type: 'refresh_token', refresh_token: process.env.REFRESH_TOKEN, client_id: process.env.CLIENT_ID, client_secret: process.env.CLIENT_SECRET }); const tokenData = response.data; // 计算过期时间:当前时间 + 有效期(提前30秒刷新) tokenExpiresAt = Date.now() + (tokenData.expires_in - 30) * 1000; currentToken = tokenData; return tokenData; } catch (error) { console.error('刷新Token失败:', error.response?.data || error.message); throw error; // 抛出错误让调用方处理 } }; // 获取有效Token的方法 exports.getValidToken = async () => { // 检查Token是否不存在或即将过期 if (!currentToken || Date.now() >= tokenExpiresAt) { return await fetchNewToken(); } return currentToken; };
2. 修改原有Token接口(可选)
如果需要保留HTTP接口供其他服务调用,可修改原getToken方法,调用Token管理模块:
const express = require('express'); const asyncHandler = require('../middlewares/async'); const tokenManager = require('./tokenManager'); exports.getToken = asyncHandler(async (req, res) => { try { const validToken = await tokenManager.getValidToken(); res.status(200).json({ accessToken: validToken }); } catch (error) { res.status(500).json({ error: '获取Token失败' }); } });
3. 在SP API调用中使用有效Token
每次调用SP API前,先获取有效Token再携带请求:
const axios = require('axios'); const tokenManager = require('./tokenManager'); // 示例:调用SP API接口 const callSPApi = async (apiUrl, method = 'GET', data = {}) => { const validToken = await tokenManager.getValidToken(); const headers = { 'Authorization': `${validToken.token_type} ${validToken.access_token}`, 'Content-Type': 'application/json' }; try { const response = await axios({ url: apiUrl, method, headers, data }); return response.data; } catch (error) { console.error('调用SP API失败:', error.response?.data || error.message); throw error; } };
关键说明
- 提前刷新机制:设置提前30秒刷新Token,避免网络延迟或Token在请求过程中过期导致失败
- 单例缓存:通过模块级变量缓存Token,保证应用内使用同一有效Token,避免重复刷新
- 错误处理:刷新Token失败时抛出错误,让业务代码可捕获并处理异常
内容的提问来源于stack exchange,提问作者tukitooo1998
相关产品推荐
相关产品推荐

