You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

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

火山引擎 最新活动