如何在Node.js后端存储JWT Token并在then外部使用?
Node.js后端保存第三方API Token的方案及作用域问题
首先解决你提到的「能不能在then回调外部使用Token」的问题:
你当前的代码里,let token定义在then回调函数内部,作用域仅限这个回调,外部根本访问不到。而且你已经用了await,完全没必要嵌套then,可以简化写法直接把返回值赋值给外部变量,这样Token就能在当前函数范围内使用了:
try { const response = await axios.post(URL); let token = response.data.access_token; // 这里token可以在当前函数的后续代码中直接使用 } catch (err) { console.log(err); res.status(404).json(err); }
如果要让Token能在应用的其他模块中使用,需要把它存储起来,以下是几种常用的实现方案:
一、内存存储(临时场景首选,重启即丢失)
在单独的模块里维护一个Token存储容器,其他模块通过导入这个模块来读写Token:
创建tokenStore.js:
let currentToken = null; module.exports = { setToken: (token) => { currentToken = token; }, getToken: () => { return currentToken; } };
获取Token的模块:
const tokenStore = require('./tokenStore'); try { const response = await axios.post(URL); const token = response.data.access_token; tokenStore.setToken(token); } catch (err) { console.log(err); res.status(404).json(err); }
其他需要用Token的模块:
const tokenStore = require('./tokenStore'); const token = tokenStore.getToken(); // 用token发起请求
注意:这种方式在服务重启、进程重启后Token会丢失;如果是多进程部署(比如PM2集群模式),每个进程内存独立,Token无法跨进程共享。
二、文件存储(简单持久化,适合低并发场景)
把Token写入本地JSON文件,重启服务后仍能读取,适合Token更新频率低的场景:
const fs = require('fs').promises; const path = require('path'); const tokenFile = path.join(__dirname, 'token.json'); // 保存Token到文件 async function saveToken(token) { await fs.writeFile(tokenFile, JSON.stringify({ accessToken: token }), 'utf8'); } // 从文件读取Token async function getToken() { try { const fileContent = await fs.readFile(tokenFile, 'utf8'); return JSON.parse(fileContent).accessToken; } catch (err) { // 文件不存在时返回null,后续可触发重新获取逻辑 return null; } } // 获取并保存Token try { const response = await axios.post(URL); const token = response.data.access_token; await saveToken(token); } catch (err) { console.log(err); res.status(404).json(err); }
其他模块调用getToken()即可获取,注意并发写入可能导致文件损坏,不适合高频率更新的场景。
三、缓存存储(生产环境推荐,支持分布式)
用Redis这类缓存数据库存储Token,支持设置过期时间,适合多服务、多进程的分布式部署场景:
先安装Redis客户端(以ioredis为例):
npm install ioredis
编写存储逻辑:
const Redis = require('ioredis'); const redis = new Redis({ host: '你的Redis服务器地址', port: 6379, // 有密码的话添加 password: '你的密码' }); // 保存Token并设置过期时间(比如2小时=7200秒) async function saveToken(token) { await redis.set('third_party_access_token', token, 'EX', 7200); } // 获取Token async function getToken() { return await redis.get('third_party_access_token'); } // 获取并保存Token try { const response = await axios.post(URL); const token = response.data.access_token; await saveToken(token); } catch (err) { console.log(err); res.status(404).json(err); }
其他模块调用getToken()就能拿到Token,这种方式支持跨进程、跨服务共享,还能自动过期,是生产环境的最优选择。
内容的提问来源于stack exchange,提问作者Anderson Santos
相关产品推荐
相关产品推荐

