Discord OAuth2授权后回调接口无限加载问题求助
问题
开发Discord OAuth2机器人时,完成授权后页面停留在callback?code=授权码地址无限加载,浏览器无响应头返回。
授权链接参数:
client_id=1151975757229326526&redirect_uri=https://verification-tejh.onrender.com/auth/discord/callback&response_type=code&scope=identify%20guilds.join
处理回调的核心代码:
app.get('/auth/discord/callback', async (req, res) => { try { const code = req.query.code; const token = await oauth.tokenRequest({ clientId: config.client.id, clientSecret: config.client.secret, code: code, scope: config.client.scope, grantType: 'authorization_code', redirectURI: config.client.redirect_uri, }); } catch (error) { console.error('Error:', error.message); res.send('Error occurred during login.'); } let user = oauth.getUser(token); let user_ = await venusClient.fetchUser(user.id); let botData = await botSchema.findOne({ clientId: client.user.id }); let ip = req.clientIp || null; if (ip) { ip = ip.split(':')[3]; } let aronshire_ = await axios.get(`https://api.ipregistry.co/${ip}?key=${config.web.apiKey}`).then(res => res.data).catch(); let countryCode = aronshire_?.location?.country?.code || null let userData = { id: user.id, username: user.username, discriminator: user.discriminator, avatar: `https://cdn.discordapp.com/avatars/${req.user.id}/${req.user.avatar}.png`, accessToken: user.accessToken, refreshToken: user.refreshToken, expiresDate: Date.now() + 604800, locale: `:flag_${countryCode.toLowerCase()}:`, ip: `${ip}`, } // 省略部分代码... venusClient.saveAuth(client.user.id, userData); venusClient.sendWebhook({/* ... */}); if (botData.autoJoin[0]?.status === true) { venusClient.joinServer(userData.accessToken, botData.autoJoin[0].guildID, userData.id); venusClient.sendWebhook({/* ... */}); } res.redirect('/verified'); });
MongoDB连接正常,请求无响应头返回,页面无限加载。
解决方案
核心问题分析
页面无限加载的本质是回调请求未返回任何响应,原因是代码中存在未捕获的异步异常,导致请求处理流程中断,没有执行到res.redirect或错误响应。
具体修复步骤
异步调用添加
await关键字oauth.getUser(token)是异步方法,未加await会返回Promise对象,后续访问user.id会得到undefined,引发未捕获异常。修改为:let user = await oauth.getUser(token);扩大try-catch覆盖范围
原代码仅捕获了tokenRequest的异常,后续逻辑出错会直接导致请求挂起。将整个路由处理逻辑放入try块:app.get('/auth/discord/callback', async (req, res) => { try { const code = req.query.code; const token = await oauth.tokenRequest({ clientId: config.client.id, clientSecret: config.client.secret, code: code, scope: config.client.scope, grantType: 'authorization_code', redirectURI: config.client.redirect_uri, }); let user = await oauth.getUser(token); let user_ = await venusClient.fetchUser(user.id); let botData = await botSchema.findOne({ clientId: client.user.id }); // 省略后续逻辑... res.redirect('/verified'); } catch (error) { console.error('Error:', error.message); res.status(500).send('Error occurred during login.'); } });修正用户头像的错误引用
userData中的avatar字段错误使用了req.user(当前请求中未赋值),替换为user对象的属性:avatar: `https://cdn.discordapp.com/avatars/${user.id}/${user.avatar}.png`,处理IP为空的情况
当ip为null时,IP查询接口请求会失效,添加判断避免无效请求:let aronshire_ = null; if (ip) { aronshire_ = await axios.get(`https://api.ipregistry.co/${ip}?key=${config.web.apiKey}`) .then(res => res.data) .catch(err => { console.error('IP查询失败:', err.message); return null; }); } let countryCode = aronshire_?.location?.country?.code || null;确保异步方法的异常被捕获
调用venusClient.saveAuth、venusClient.sendWebhook等方法时,如果存在异步逻辑,需添加await并确保异常被try-catch覆盖,避免流程中断。
内容的提问来源于stack exchange,提问作者sub joel
相关产品推荐
相关产品推荐

