You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

调用Destiny 2 API通过POST获取auth token返回400错误该如何解决?

问题修复方案

1. POST请求400错误修复

你当前请求返回400的核心原因是缺失了Bungie OAuth接口要求的认证配置,以及部分场景参数不符合规范,修复逻辑如下:

  • 首先确认你在Bungie开发者平台注册的应用类型:
    • 如果是Confidential(机密类型)应用:需要将client_id:client_secret做Base64编码后,添加到请求头的Authorization字段中,格式为Basic 编码结果。注意该类应用的client_secret不能暴露在前端代码中,建议走后端代理请求token接口,避免密钥泄露。
    • 如果是Public(公开类型,面向前端场景)应用:无需传递Basic认证头,只需保证body中填写的client_id与注册信息一致即可。
  • 补充错误日志打印:你当前只打印了response对象,没有读取响应体中的错误提示,400响应体中会明确返回invalid_grant、invalid_client等错误码,可直接定位具体问题。

修复后的请求代码示例:

document.getElementById("linkButton").addEventListener("click", async function(event) {
  // 公开类型应用仅需填写client_id,机密类型应用需走后端代理,禁止在前端暴露client_secret
  const clientId = "替换为你的client_id";
  try {
    const response = await fetch('https://www.bungie.net/Platform/App/OAuth/token/', {
      method: 'POST',
      headers: {
        'Content-Type': 'application/x-www-form-urlencoded',
        // 机密类型应用需在后端添加Authorization: Basic base64(client_id:client_secret)头
      },
      body: new URLSearchParams({
        'client_id': clientId,
        'grant_type': "authorization_code",
        'code': authCode
      })
    });
    const result = await response.json();
    console.log('接口返回详情:', result);
    if (!response.ok) throw new Error(result.error || response.statusText);
    // 后续可将返回的access_token、refresh_token存储在本地,用于调用其他业务接口
  } catch (err) {
    console.error('请求失败:', err);
  }
});

额外校验点:

  • 授权码有效期非常短,拿到后需要在1分钟内发起请求,超时会失效
  • 回调地址必须和开发者平台配置的完全一致,包括协议(http/https)、域名、端口、路径,任何差异都会导致code无效
  • 必须校验state参数,防止CSRF攻击

2. 授权码提取逻辑优化

你当前用字符串截取的方式边界兼容性非常差,比如code是URL最后一个参数时,找不到后续的&符号会导致截取结果错误。可以直接使用浏览器内置的URLSearchParamsAPI处理查询参数,代码更简洁兼容性更强:

// 生成state时存储到本地,用于后续校验
document.getElementById("authButton").addEventListener("click", function(event) {
  const state = makeState(32);
  localStorage.setItem('oauth_state', state);
  location.href = `https://www.bungie.net/en/OAuth/Authorize?client_id={my-client-id}&response_type=code&state=${state}`;
});

// 回调后提取授权码
let authCode;
const urlParams = new URLSearchParams(window.location.search);
const returnedState = urlParams.get('state');
const storedState = localStorage.getItem('oauth_state');
// 先校验state一致性,避免CSRF攻击
if (urlParams.has('code') && returnedState === storedState) {
  removeAuthButton();
  authCode = urlParams.get('code');
  console.log('提取到的授权码:', authCode);
  // 校验完成后清除存储的state
  localStorage.removeItem('oauth_state');
}

3. 问题格式优化建议

你当前的提问结构已经非常清晰,后续如果提问可以补充上响应体的具体错误内容,能够更快定位问题。

内容的提问来源于stack exchange,提问作者Max

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.30 00:18:04