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

使用Discord API实现「Login with Discord」(OAuth)时请求资源被拒绝的问题求助

解决Discord OAuth前端请求API的CORS问题

看起来你遇到的是**浏览器跨域资源共享(CORS)**限制的问题,同时还有几个需要注意的安全和权限细节,我来一步步帮你解决:

为什么会出现"Not allowed to request source"错误?

Discord的API(尤其是/guilds/{guild_id}/members/{user_id}这类接口)并不支持前端直接发起跨域请求——浏览器会因为CORS策略阻止这种请求,而且直接在前端暴露access_token是非常不安全的,恶意用户可以拿到这个token去操作你的账号权限。

正确的解决方案:通过后端代理请求

你需要搭建一个简单的后端服务,由后端来调用Discord的API,前端只和自己的后端交互,这样既避开CORS限制,又能保护access_token不泄露。

步骤1:确认OAuth授权范围

首先,你在发起Discord OAuth授权请求时,必须包含对应的权限范围:

  • 要获取用户基本信息:identify
  • 要获取用户在公会中的角色:guilds.members.read
    确保你的授权URL里包含这些scope参数,比如:
https://discord.com/api/oauth2/authorize?client_id=YOUR_CLIENT_ID&redirect_uri=YOUR_REDIRECT_URI&response_type=token&scope=identify%20guilds.members.read

步骤2:搭建后端代理(示例用Node.js/Express)

创建一个简单的后端接口,接收前端传来的access_token和token_type,然后由后端去调用Discord API:

const express = require('express');
const fetch = require('node-fetch');
const app = express();
const cors = require('cors');

app.use(cors());
app.use(express.json());

app.post('/discord-guild-member', async (req, res) => {
  const { accessToken, tokenType, guildId, userId } = req.body;
  try {
    const response = await fetch(`https://discord.com/api/guilds/${guildId}/members/${userId}`, {
      headers: {
        Authorization: `${tokenType} ${accessToken}`
      }
    });
    const data = await response.json();
    res.json(data);
  } catch (error) {
    res.status(500).json({ error: error.message });
  }
});

app.listen(3000, () => console.log('Backend running on port 3000'));

步骤3:修改前端代码,调用自己的后端接口

现在前端不再直接请求Discord API,而是请求你的后端:

window.onload = () => { 
  const fragment = new URLSearchParams(window.location.hash.slice(1)); 
  const accessToken = fragment.get('access_token'); 
  const tokenType = fragment.get('token_type');

  // 先获取用户自己的ID(从/users/@me接口)
  fetch('https://discord.com/api/users/@me', { 
    headers: { 
      authorization: `${tokenType} ${accessToken}`, 
    }, 
  })
  .then(result => result.json())
  .then(user => {
    const userId = user.id;
    const guildId = '874613987487121408'; // 你的公会ID

    // 调用后端代理接口
    fetch('http://localhost:3000/discord-guild-member', {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json'
      },
      body: JSON.stringify({
        accessToken,
        tokenType,
        guildId,
        userId
      })
    })
    .then(result => result.json())
    .then(response => {
      const username = response.user.username;
      const roles = response.roles.join(', ');
      document.getElementById('info').innerText = `用户名: ${username}\n角色ID列表: ${roles}`;
    })
    .catch(console.error);
  })
  .catch(console.error); 
};

额外注意事项

  • 不要在前端硬编码固定的用户ID,应该先通过/users/@me接口获取当前授权用户的ID,再去查询公会成员信息。
  • 后端部署时,要确保你的域名是安全的(HTTPS),避免token在传输过程中被窃取。
  • 如果你的应用需要处理多个用户,记得在后端做好token的验证和过期处理。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.28 19:22:48