Im making a website with dashboard for a discord bot. Only when im making the authorization page with the help of JWT to make a token it keeps giving me a headers error (see below). Ill put my code for that specific item under here. Can someone please help me out because I can’t seem to find any source of why said error pops up.
Error:
node:_http_outgoing:703
throw new ERR_HTTP_HEADERS_SENT('set');
^
Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client
at ServerResponse.setHeader (node:_http_outgoing:703:11)
at ServerResponse.header (C:xampphtdocsdiscordapiapinode_modulesexpresslibresponse.js:795:10)
at ServerResponse.send (C:xampphtdocsdiscordapiapinode_modulesexpresslibresponse.js:175:12)
at ServerResponse.json (C:xampphtdocsdiscordapiapinode_modulesexpresslibresponse.js:279:15)
at C:xampphtdocsdiscordapiapisrcroutesauthindex.js:109:32
at process.processTicksAndRejections (node:internal/process/task_queues:95:5) {
code: 'ERR_HTTP_HEADERS_SENT'
}
Node.js v21.6.0
Failed running '.'
Code:
const express = require('express');
const User = require('../../models/User');
const jwt = require('jsonwebtoken');
const router = express.Router();
// GET: designy.xyz/auth/signin
// GET: designy.xyz/auth/callback
const DASHBOARD_URL = 'http://localhost:5173';
router.get('/signin', (req, res) => {
res.redirect(
`https://discord.com/oauth2/authorize?client_id=${process.env.DISCORD_CLIENT_ID}&response_type=code&redirect_uri=http%3A%2F%2Flocalhost%3A3001%2Fauth%2Fcallback&scope=guilds+identify`
);
});
router.get('/callback', async (req, res) => {
const DISCORD_ENDPOINT = 'https://discord.com/api/v10';
const CLIENT_ID = process.env.DISCORD_CLIENT_ID;
const CLIENT_SECRET = process.env.DISCORD_CLIENT_SECRET;
const REDIRECT_URI = process.env.DISCORD_REDIRECT_URI;
const DASHBOARD_URL = process.env.DASHBOARD_URL;
const { code } = req.query;
if (!code) {
return res.status(400).json({
error: 'A "code" query parameter must be present in the URL.',
});
}
try {
const oauthRes = await fetch(`${DISCORD_ENDPOINT}/oauth2/token`, {
method: 'POST',
body: new URLSearchParams({
client_id: CLIENT_ID,
client_secret: CLIENT_SECRET,
grant_type: 'authorization_code',
redirect_uri: REDIRECT_URI,
code,
}).toString(),
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
},
});
if (!oauthRes.ok) {
return res.status(500).json({
error: 'Failed to obtain OAuth token.',
});
}
const oauthResJson = await oauthRes.json();
const userRes = await fetch(`${DISCORD_ENDPOINT}/users/@me`, {
method: 'GET',
headers: {
Authorization: `Bearer ${oauthResJson.access_token}`,
},
});
if (!userRes.ok) {
return res.status(500).json({
error: 'Failed to fetch user data.',
});
}
const userResJson = await userRes.json();
let user = await User.findOne({ id: userResJson.id });
if (!user) {
user = new User({
id: userResJson.id,
username: userResJson.username,
avatarHash: userResJson.avatar,
accessToken: oauthResJson.access_token,
refreshToken: oauthResJson.refresh_token,
});
} else {
user.username = userResJson.username;
user.avatarHash = userResJson.avatar;
user.accessToken = oauthResJson.access_token;
user.refreshToken = oauthResJson.refresh_token;
}
await user.save();
const token = jwt.sign(
{
id: userResJson.id,
username: userResJson.username,
avatarHash: userResJson.avatar,
},
process.env.JWT_SECRET,
{ expiresIn: '7d' }
);
res.cookie('access_token', token, {
httpOnly: true,
secure: process.env.NODE_ENV === 'production',
maxAge: 6.048e8,
});
return res.redirect(DASHBOARD_URL);
} catch (error) {
console.error(error);
return res.status(500).json({
error: 'Internal Server Error.',
});
}
});
router.get('/signout', (req, res) => {
res.clearCookie('token').sendStatus(200);
});
module.exports = router;
Help would be much appreciated!
Ive tried to remove the .send .json. status to see if that would fix the issue.
Ive also tried to remove the res.redirect + token to see if that would’ve helped
Both of these things did not work, also tried some other things but i can’t remember them anymore.