Node.js中如何获取AWS Cognito token并导出供其他文件使用
核心问题说明
authenticateUser 是异步回调方法,你如果直接在onSuccess回调里给变量赋值再导出,会出现时序问题:其他文件引入的时候,回调还没执行,拿到的永远是undefined。正确的做法是把回调逻辑封装成Promise,导出可异步调用的获取token方法,必要时加缓存避免重复认证。
第一步:改造Cognito认证模块
把你现有的认证逻辑单独放到cognitoAuth.js文件里,封装成可复用的异步方法,代码如下:
const { AuthenticationDetails, CognitoUser, CognitoUserPool } = require("amazon-cognito-identity-js"); const poolData = { UserPoolId : '', // 替换成你的用户池ID ClientId : '' // 替换成你的客户端ID }; const userPool = new CognitoUserPool(poolData); // 缓存token,避免重复调用认证接口 let cachedIdToken = null; /** * 获取Cognito ID Token * @param {boolean} forceRefresh 是否强制刷新token * @returns {Promise<string>} JWT Token */ function getCognitoToken(forceRefresh = false) { // 已有缓存且不强制刷新时直接返回缓存值 if (cachedIdToken && !forceRefresh) { return Promise.resolve(cachedIdToken); } const userData = { Username : '', // 替换成你的用户名 Pool : userPool }; const cognitoUser = new CognitoUser(userData); const authenticationData = { Username: '', // 替换成你的用户名 Password: '', // 替换成你的密码 }; const authenticationDetails = new AuthenticationDetails(authenticationData); return new Promise((resolve, reject) => { cognitoUser.authenticateUser(authenticationDetails, { onSuccess: function(data) { const idToken = data.getIdToken().getJwtToken(); cachedIdToken = idToken; resolve(idToken); }, onFailure: function(err) { // 认证失败清空缓存 cachedIdToken = null; reject(err); } }) }) } module.exports = { getCognitoToken };
注意:你原来的代码漏写了
onFailure回调,认证失败(比如密码错误、网络超时)时会直接吞掉错误,必须加上错误捕获逻辑。
第二步:在其他文件中调用
在任何需要用到token的文件里,引入上面的模块,用async/await调用即可:
// 其他业务文件,比如api.js const { getCognitoToken } = require('./cognitoAuth'); async function callProtectedApi() { try { // 第一次调用会走认证流程,后续调用直接拿缓存 const token = await getCognitoToken(); console.log('拿到的token:', token); // 后续把token放到请求头里调用需要鉴权的接口即可 // 比如:headers: { Authorization: `Bearer ${token}` } } catch (err) { console.error('获取token失败:', err); // 处理认证失败的逻辑,比如返回登录错误提示 } } // 需要用token的时候直接调用这个方法就行 callProtectedApi();
可选优化
- 如果是长期运行的Node服务,可以给缓存加过期判断:Cognito返回的idToken默认有效期1小时,可以在缓存时同时存过期时间,快过期时自动刷新,避免接口请求时拿过期token报错
- 不要在模块加载时就立刻执行认证逻辑存全局变量,一旦启动时网络波动、账号密码错误,会直接导致服务启动失败,用的时候按需调用更稳妥
- 敏感配置(用户池ID、账号密码)不要硬编码在代码里,放到环境变量里读取更安全
内容的提问来源于stack exchange,提问作者1111
相关产品推荐
相关产品推荐

