Node.js使用HTTPS发送x-www-form-urlencoded请求获取API Token问题求助
问题排查及修复方案
现有代码的错误点
- 基础语法错误:初始代码中
let = tokenPayload = {多写了等号,属于语法错误 - client_assertion_type参数值多了末尾的斜杠:官方要求值为
urn:ietf:params:oauth:client-assertion-type:jwt-bearer,你的代码中多写了/,属于参数值错误 - JWT payload的
exp字段配置错误:exp要求传入Unix时间戳(单位秒),直接写300代表的是1970年1月1日的时间,属于已过期的无效签名,正确写法是当前时间戳加300秒 - 原生https请求没有正确处理请求体:https模块不会自动序列化和发送payload,需要手动将参数转为x-www-form-urlencoded格式,同时设置正确的Content-Type请求头,再将序列化后的内容写入请求
- axios版本没有显式指定Content-Type请求头,部分场景下会导致服务端无法识别请求格式
- 可选优化点:jti字段建议使用随机唯一值,固定写
1可能会被服务端防重放校验拦截,可替换为require('crypto').randomUUID()生成的唯一值
原生https模块修复后的完整代码
const fs = require('fs'); const https = require('https'); const querystring = require('querystring'); const ConfigParams = JSON.parse(fs.readFileSync('Config.json', 'utf8')); const jwt = require('jsonwebtoken'); const apikey = ConfigParams.client_id; const privateKey = fs.readFileSync(**MY KEY**); const API_HOST = **HOST**; const API_PATH = **PATH**; const jwtOptions = { algorithm: 'RS512', header: { kid: 'test-1' } } const jwtPayload = { iss: apikey, sub: apikey, aud: **API TOKEN ENDPOINT**, jti: require('crypto').randomUUID(), exp: Math.floor(Date.now() / 1000) + 300 } jwt.sign(jwtPayload, privateKey, jwtOptions, (err, token) => { if (err) { console.error('JWT签名失败:', err); return; } const tokenPayload = { grant_type: 'client_credentials', client_assertion_type: 'urn:ietf:params:oauth:client-assertion-type:jwt-bearer', client_assertion: token } const postData = querystring.stringify(tokenPayload); const tokenAuthOptions = { host: API_HOST, path: API_PATH, method: 'POST', headers: { 'Content-Type': 'application/x-www-form-urlencoded', 'Content-Length': Buffer.byteLength(postData) } } const req = https.request( tokenAuthOptions, resp => { let body = ''; resp.on('data', chunk => { body += chunk; }); resp.on('end', () => { console.log('响应状态码:', resp.statusCode); console.log('响应内容:', body); }); } ); req.on('error', e => { console.error('请求出错:', e); }); req.write(postData); req.end(); } )
axios版本修复代码
const url = require('url'); const axios = require('axios'); // 前置JWT生成逻辑和上述修复方案一致,生成有效token后执行以下代码 const params = new url.URLSearchParams({ grant_type: 'client_credentials', client_assertion_type: 'urn:ietf:params:oauth:client-assertion-type:jwt-bearer', client_assertion: tkn }); axios.post("替换为实际的接口请求地址", params.toString(), { headers: { 'Content-Type': 'application/x-www-form-urlencoded' } }).then(resp => { console.log("响应状态码: " + resp.status); console.log("响应内容: ", resp.data); }).catch(err => { console.log("请求出错: ", err.response ? err.response.data : err.message); })
内容的提问来源于stack exchange,提问作者Craig
相关产品推荐
相关产品推荐

