I want to create a login system with discord and I think I'm doing everything fine
but it's still not working.
This is my code:
require("dotenv").config();
const cookieSession = require("cookie-session");
const express = require("express");
const fetch = require("node-fetch");
const PORT = process.env.PORT;
const app = express();
const AUTH_URL = "https://discord.com/api/oauth2/authorize?client_id=928706322701119528&redirect_uri=http%3A%2F%2Flocalhost%3A4044%2Fapi%2Fauth%2Fcallback&response_type=code&scope=identify";
const params = new URLSearchParams({
client_id: process.env.CLIENT_ID,
client_secret: process.env.CLIENT_SECRET,
grant_type: "authorization_code",
redirect_uri: encodeURI("http://localhost:4044/api/auth"),
scope: "identify"
});
app.use(express.static(path.join(__dirname, "public")))
app.use(cookieSession({
name: "pprp",
keys: [
"abcde"
],
maxAge: 24 * 60 * 60 * 1000
}));
app.get("/", (req, res) => {
res.redirect(AUTH_URL);
});
app.get("/api/auth/callback", (req, res) => {
const code = req.query.code;
if(!code) return res.send("Invalid code");
params.append("code", encodeURI(code));
console.log("https://discord.com/api/oauth2/token?" + params.toString())
fetch("https://discord.com/api/oauth2/token?" + params.toString(), {
method: "post",
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
}
}).then(response => response.json()).then(data => console.log(data)); // Here it's prints { error: 'invalid_client' }
});
app.listen(PORT, () => console.log(`Listening on ${PORT}`))
but in line 47 it's retuning invaild_client in the request and I don't know why
I tried to check if the client_id is undefined or the client_secret I tried to switch applications.
Related
I am currently learning how to use the fetch api for my front-end. I continue to get the XHR 404 POST error.
//Backend file
const express = require("express");
const app = express();
require("dotenv");
const Port = process.env.PORT || 5000;
app.use(express.static("public"));
app.use(express.json());
app.use(
express.urlencoded({
extended: false,
})
);
const nodemailer = require("nodemailer");
const Mail = require("nodemailer/lib/mailer");
require("nodemailer-mailgun-transport");
app.use(express.json());
app.get("/", (req, res) => {
res.sendFile("/public");
res.sendFile("/public/js/mail.js");
});
app.listen(Port, (req, res) => {
console.log(`listening on port ${Port}`);
});
app.post("/email"),
(req, res) => {
FromMailjs = req.body;
console.log(FromMailjs);
const transporter = nodemailer.createTransport({
auth: {
user: process.env.Email,
pass: process.env.Pass,
},
});
const MailOptions = {
from: req.body.Email,
to: process.env.MyEmail,
text: `${req.body.FirstName}, ${req.body.LastName}
, ${req.body.PhoneNumber}, ${req.body.Email}`,
};
transporter.sendMail(MailOptions, (error, info) => {
if (error) {
console.log(error);
res.send("error");
} else {
console.log("Email sent");
res.send("success");
}
});
};
//Frontend file
const ContactForm = document.querySelector(".contact-form");
ContactForm.addEventListener("submit", (e) => {
e.preventDefault();
let FirstName = document.getElementById("Fname");
let LastName = document.getElementById("Lname");
let PhoneNumber = document.getElementById("PhoneNumber");
let Email = document.getElementById("Email");
const FormData = {
FirstName: FirstName.value,
LastName: LastName.value,
PhoneNumber: PhoneNumber.value,
Email: Email.value,
};
const PostOptions = {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify(FormData),
};
console.log(FormData);
fetch("/email", PostOptions);
});
XHRPOSThttp://localhost:5000/email
[HTTP/1.1 404 Not Found 27ms]
I have tried changing the routes hoping that it was just a routing issue and I still get the same error. I was using XHR before fetch and I got the same 404 error. My front-end is receiving the correct information but I can't get my backend to receive the information.
You have a typo. Please use:
app.post("/email", (req, res) => {
Instead of:
app.post("/email"),
(req, res) => {
I am trying to get data from a udemy API. I can get it with cURL in the console but not with fetch. Please can anyone look at my code and let me know what I am doing wrong?
const fetch = require("node-fetch");
const express = require("express");
const app = express();
const port = process.env.PORT || 3000;
const path = require("path");
app.use(express.static("public"));
app.use(express.static(path.resolve(__dirname, "public")));
app.get("/", (req, res) => {
res.sendFile("index.html", { root: __dirname });
});
app.get("/contact", (req, res) => {
res.sendFile("contact.html", { root: __dirname });
});
const client_id = "client_id";
const client_secret = "client_secret";
const client = Buffer.from(`${client_id}:${client_secret}`).toString("base64");
fetch("https://www.udemy.com/api-2.0/courses/", {
headers: {
Authorization: `Basic ${client}`,
},
})
.then((res) => res.json())
.then((json) => console.log(json))
.catch((err) => {
console.log(err);
});
In this code i have added express endpoints to get twilio endpoints
const config = require("./config");
const express = require("express");
const bodyParser = require("body-parser");
const pino = require("express-pino-logger")();
const { videoToken } = require("./tokens");
const app = express();
app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());
app.use(pino);
const sendTokenResponse = (token, res) => {
res.set("Content-Type", "application/json");
res.send(
JSON.stringify({
token: token.toJwt(),
})
);
};
app.post("/video/token", (req, res) => {
const identity = req.body.identity;
const room = req.body.room;
const token = videoToken(identity, room, config);
sendTokenResponse(token, res);
});
In this code i have added function to fetch twilio endpoints but i don't know why it's throwing error of JSON unexpected token at position 0 maybe it's twilio error
const handleSubmit = useCallback(async () => {
setConnecting(true);
const data = await fetch("/video/token", {
method: "POST",
body: JSON.stringify({
identity: username,
room: roomName,
}),
headers: {
Accept: "application/json",
"Content-Type": "application/json",
},
}).then((res) => res.json());
Video.connect(data.token, {
name: roomName,
})
.then((room) => {
setConnecting(false);
setRoom(room);
})
.catch((err) => {
console.error(err);
setConnecting(false);
});
}, [roomName, username]);
So i am trying to create a discord bot dashboard and I am including a Discord Oauth2 to get User information. My Discord Oauth2 works, however after authorising, it redirects me to the homepage but the URL has token=undefined . The console does log "It works!". How do I fix the undefined access token?
http://localhost:3000/?token=undefined
var path = require('path');
const express = require('express');
const fetch = require('node-fetch');
const app = express();
require('dotenv').config();
const btoa = require('btoa');
const { catchAsync } = require('./utils.js')
const CLIENT_ID = process.env.CLIENT_ID;
const CLIENT_SECRET = process.env.CLIENT_SECRET;
const redirect = encodeURIComponent('http://localhost:3000/callback');
...
app.get('/login', (req, res) => {
res.redirect(`https://discord.com/api/oauth2/authorize?client_id=${CLIENT_ID}&redirect_uri=${redirect}&response_type=code&scope=identify%20email%20guilds`);
});
app.get('/callback', catchAsync(async (req, res) => {
if (!req.query.code) throw new Error('NoCodeProvided');
const code = req.query.code;
const creds = btoa(`${CLIENT_ID}:${CLIENT_SECRET}`);
const response = await fetch(`https://discordapp.com/api/oauth2/token?grant_type=authorization_code&code=${code}&redirect_uri=${redirect}`,
{
method: 'POST',
headers: {
Authorization: `Basic ${creds}`,
},
});
const json = await response.json();
console.log("it works!")
res.redirect(`/?token=${json.access_token}`);
}));
app.listen(3000)
There seemed to be a problem with how the callback link was set up, So I changed it to look like this and it works.
app.get('/callback', catchAsync(async (req, res) => {
const data = {
client_id: CLIENT_ID,
client_secret: CLIENT_SECRET,
grant_type: 'authorization_code',
redirect_uri: redirect,
code: req.query.code,
scope: ['identify', 'email', 'guilds'],
};
const response = await fetch('https://discord.com/api/oauth2/token', {
method: 'POST',
body: new URLSearchParams(data),
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
}
})
const json = await response.json();
const fetchDiscordUserInfo = await fetch('http://discordapp.com/api/users/#me', {
headers: {
Authorization: `Bearer ${json.access_token}`,
}
});
const userInfo = await fetchDiscordUserInfo.json();
res.redirect('http://localhost:3000/dashboard')
console.log(userInfo);
I get the following error when I try to authenticate with passport. I wonder if I am missing some middleware or something. What ever the case, this just is not working at the moment. I am getting the following error on the backend:
] { message: 'You should provide access_token' }
[0] Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client
App.js:29 POST http://127.0.0.1:3000/api/users/auth/facebook 401 (Unauthorized)
I have made sure that the access token prints on the frontend:
this is ther token blob {"access_token":"EAAGTZAFMSr8YBACcmZAaEaEMTbCKICwJqiohySMxb1pPrJaaECiPqfOqiPFln4hp2pucvSm9Pr42twDQVZBt4KZAIoEENaAINHVBcfZB8YdRM23Y9VjDSeSnUtOsyynufjCBdQyNozpI2N4bTJotZAEmLETjIqLZBxwP9VxBdDFZAYWMofEiZCUDrQwGk7fBahs8SEtzTB80kfAZDZD"}
Here is the frontend
facebookResponse = (response) => {
const token= JSON.stringify({access_token: response.accessToken}, {type : 'application/json'});
console.log('this is ther token blob', token);
const options = {
method: 'POST',
body: token,
mode: 'cors',
cache: 'default'
};
fetch('api/users/auth/facebook', options).then(r => {
const token = r.headers.get('x-auth-token');
if(token){
try {
r.json().then(user => {
if (token) {
this.setState({isAuthenticated: true, user, token})
}
});
} catch{
console.log('error');
}
}
})
};
Here is the backend
var express = require('express');
var router = express.Router();
var { generateToken, sendToken } = require('./token.utils');
var passport = require('passport');
var config = require('./config');
var request = require('request');
require('../../passport')();
router.use(passport.initialize());
router.use(passport.session());
router.post('/auth/facebook',
function(req, res, next){
passport.authenticate('facebook-token', function(error, user, info){
console.log(error);
console.log(user);
console.log(info);
if (error) {
res.status(401).send(error);
} else if (!user) {
res.status(401).send(info);
} else {
next();
}
res.status(401).send(info);
})(req, res);
});
module.exports = router;
Here is my jwt strategy I am using facebook login:
require('./mongoose')();
var passport = require('passport');
var User = require('mongoose').model('User');
var FacebookTokenStrategy = require('passport-facebook-token');
module.exports = function () {
passport.use(new FacebookTokenStrategy({
clientID: '443534076456---',
clientSecret: 'd9c12cd1c8c7fcea7abb391a0bbb---'
},
function (accessToken, refreshToken, profile, done) {
User.upsertFbUser(accessToken, refreshToken, profile, function(err, user) {
return done(err, user);
});
}));
};
Here is the main server file:
const express = require('express');
const mongoose = require('mongoose');
const bodyParser = require('body-parser');
const passport = require('passport');
const path = require('path');
const users = require('./routes/api/users');
const cors = require('cors');
const app = express();
app.use(bodyParser.urlencoded({extended: false}));
app.use(bodyParser.json());
var corsOption = {
origin: true,
methods: 'GET,HEAD,PUT,PATCH,POST,DELETE',
credentials: true,
exposedHeaders: ['x-auth-token']
};
app.use(cors());
// const db = require('./config/keys').mongoURI;
// mongoose.connect("mongodb://user1:Voodoo12#ds263146.mlab.com:63146/fb-login-chat").then(()=> console.log('MongoDb Connected'))
// .catch(err=> console.log(err));
app.use(express.static(path.join(__dirname, 'public')));
app.use(passport.initialize());
app.use(passport.session());
app.use('/api/users', users);
//serve static assets if in production
// if(process.env.NODE_ENV === 'production'){
// //Set a static folder
// app.use(express.static('client/build'))
// app.get('*', (req, res)=>{
// res.sendFile(path.resolve(__dirname, 'client', 'build', 'index.html'));
// });
// }
const port = process.env.PORT || 5000;
app.listen(port, () => console.log(`Server running on port ${port}`));
I thinks your API is not able to decode the payload and extract your access token
try to add headers in yours options for the request
const options = {
method: 'POST',
body: token,
mode: 'cors',
cache: 'default',
// add headers
headers: { 'Content-type': 'application/json' }
};
Regards,
MA