I'm creating a Discord login, but when I get redirected, I get the error. The error happens after I press authorize on the Discord OAuth page
{"status":"ERROR","error":"Response code 400 (Bad Request)"}
Here is my code for Discord.js
const express = require('express');
const router = express.Router();
const fetch = require('got');
const btoa = require('btoa');
const { catchAsync } = require('../utils');
const CLIENT_ID = '#';
const CLIENT_SECRET = '#';
const redirect = encodeURIComponent('https://ezapplications.live/api/discord/callback');
router.get('/callback', catchAsync(async (req, res) => {
if (!req.query.code) throw new Error('NoCodeProvided');
const response = await fetch(`https://discordapp.com/api/oauth2/authorize?client_id=${CLIENT_ID}&scope=identify&response_type=code&redirect_uri=${redirect}`, {
method: 'POST',
body: new URLSearchParams({
client_id: CLIENT_ID,
client_secret: CLIENT_SECRET,
grant_type: "authorization_code",
redirect_uri: "https://ezapplications.live/api/discord/callback",
code: req.query.code
})
});
const json = await response.json();
res.redirect(`/?token=${json.access_token}`);
}));
router.get('/login', (req, res) => {
res.redirect(`https://discordapp.com/api/oauth2/authorize?client_id=${CLIENT_ID}&scope=identify&response_type=code&redirect_uri=${redirect}`);
});
module.exports = router;
Here is my code for Server.js
const express = require('express');
const path = require('path');
const app = express();
app.get('/', (req, res) => {
res.status(200).sendFile(path.join(__dirname, 'index.html'));
});
app.use('/api/discord', require('./api/discord'));
app.use((err, req, res, next) => {
switch (err.message) {
case 'NoCodeProvided':
return res.status(400).send({
status: 'ERROR',
error: err.message,
});
default:
return res.status(500).send({
status: 'ERROR',
error: err.message,
});
}
});
app.listen(50451, () => {
console.info('Running on port 50451');
});
Here is the code for utils.js
// async/await error catcher
const catchAsyncErrors = fn => (
(req, res, next) => {
const routePromise = fn(req, res, next);
if (routePromise.catch) {
routePromise.catch(err => next(err));
}
}
);
exports.catchAsync = catchAsyncErrors;
I'm not sure why I get this error as everything seems fine to me, thanks.
CodePudding user response:
As per the Authorization Code Grant docs, you need to pass the parameters in the request body instead of the query string.
const response = await fetch("https://discord.com/api/oauth2/token", {
method: 'POST',
headers: {
"content-type": "application/x-www-form-urlencoded"
},
body: new URLSearchParams({
client_id: CLIENT_ID,
client_secret: CLIENT_SECRET,
grant_type: "authorization_code",
redirect_uri: "https://ezapplications.live/api/discord/callback",
code: req.query.code
}).toString()
});
Regarding HTTP Basic auth...
You can also pass your
client_id
andclient_secret
as basic authentication withclient_id
as the username andclient_secret
as the password
...but I don't really see the point. Your choice