Node.js中如何获取UPS OAuth授权重定向后的查询参数并传递给令牌生成函数
Node.js中如何获取UPS OAuth授权重定向后的查询参数并传递给令牌生成函数
看起来你已经把UPS OAuth流程的第一步走通了——能成功唤起Chrome登录、授权后也能跳转到指定地址拿到code,这已经很棒了!现在的核心问题就是怎么自动捕获这个重定向URL里的code参数,不用手动复制粘贴到代码里对吧?
其实解决思路很简单:你需要在本地搭一个临时的HTTP服务器,用来接收UPS的重定向请求,这样Node.js就能直接从请求里提取出code,再把它传给generateToken函数。下面是具体的实现步骤和修改后的代码:
第一步:调整重定向URI配置
首先,你需要把UPS开发者平台里的允许重定向URI,加上一个本地地址(比如http://localhost:3000/callback),同时把代码里的redirect_uri都改成这个本地地址——UPS不允许随便跳转到未配置的地址,这一步一定要做!
第二步:修改代码,加入本地服务器逻辑
我们用Node.js内置的http模块来搭一个轻量服务器,监听回调请求,提取code后调用令牌生成函数:
import fetch from 'node-fetch'; import open from 'open'; import http from 'http'; import url from 'url'; // 建议把这些敏感信息放到环境变量里,不要硬编码! const UPS_CLIENT_ID = 'myClientID'; const UPS_CLIENT_SECRET = 'upsPassword'; const REDIRECT_URI = 'http://localhost:3000/callback'; async function getAuthorizationURL() { const query = new URLSearchParams({ client_id: UPS_CLIENT_ID, redirect_uri: REDIRECT_URI }).toString(); const resp = await fetch( `https://onlinetools.ups.com/security/v1/oauth/validate-client?${query}`, { method: 'GET' } ); const data = await resp.json(); const reqType = data['type']; const signInParams = new URLSearchParams({ client_id: UPS_CLIENT_ID, redirect_uri: REDIRECT_URI, response_type: 'code', scope: 'read', type: reqType }).toString(); const signInUrl = `https://www.ups.com/lasso/signin?${signInParams}`; console.log('打开登录页:', signInUrl); await open(signInUrl, { app: { name: 'chrome' } }); } async function generateToken(authorizationCode) { const formData = { grant_type: 'authorization_code', code: authorizationCode, redirect_uri: REDIRECT_URI }; const resp = await fetch( `https://onlinetools.ups.com/security/v1/oauth/token`, { method: 'POST', headers: { 'Content-Type': 'application/x-www-form-urlencoded', 'x-merchant-id': UPS_CLIENT_ID, Authorization: 'Basic ' + Buffer.from(`${UPS_CLIENT_ID}:${UPS_CLIENT_SECRET}`).toString('base64') }, body: new URLSearchParams(formData).toString() } ); const data = await resp.json(); console.log('获取到的令牌信息:', data); // 这里可以把令牌存起来,比如写到文件或者数据库里 } // 启动本地服务器监听回调 function startCallbackServer() { const server = http.createServer((req, res) => { // 解析请求URL的查询参数 const queryParams = url.parse(req.url, true).query; if (req.url.startsWith('/callback') && queryParams.code) { const authorizationCode = queryParams.code; console.log('捕获到授权码:', authorizationCode); // 返回一个简单的页面提示用户授权完成 res.writeHead(200, { 'Content-Type': 'text/html' }); res.end('<h1>授权完成!可以关闭这个页面了</h1>'); // 调用令牌生成函数 generateToken(authorizationCode).then(() => { // 令牌生成完成后关闭服务器 server.close(() => { console.log('回调服务器已关闭'); }); }).catch(err => { console.error('生成令牌出错:', err); server.close(); }); } else { res.writeHead(404); res.end('Not Found'); } }); server.listen(3000, () => { console.log('回调服务器已启动,监听http://localhost:3000/callback'); // 服务器启动后再打开授权页 getAuthorizationURL().catch(err => { console.error('获取授权URL出错:', err); server.close(); }); }); } // 启动整个流程 startCallbackServer();
关键细节说明
- 本地服务器的作用:UPS授权完成后会跳转到我们配置的
http://localhost:3000/callback,这个服务器会捕获这个请求,从URL的查询参数里提取code。 - 异步流程处理:我们先启动服务器,再打开授权页,确保服务器已经准备好接收回调;生成令牌后关闭服务器,避免一直占用端口。
- 敏感信息管理:把
client_id、密码这些敏感信息放到环境变量里(比如用dotenv包),不要直接写在代码里,这是生产环境的最佳实践。 - 错误处理:代码里加了基本的错误捕获,避免某个环节出错后整个程序挂掉。
这样修改后,你运行代码就会自动打开Chrome登录,授权完成后浏览器会跳转到本地的回调地址,Node.js会自动提取code并生成令牌,完全不用手动复制啦!
备注:内容来源于stack exchange,提问作者matthh




