I can't figure out how to query the MySQL database from the promise in my route file. I'm writing a RESTful API to query a MySQL database with GET methods. I'm using Express and Axios for Javascript promises.
I want to get back the list of books from a SQL table and the count of how many listings in the returned JSON.
server.js
const http = require('http');
const app = require('./app');
const port = process.env.PORT || 3000;
const server = http.createServer(app);
server.listen(port);
app.js
const express = require('express');
const app = express();
const morgan = require('morgan');
const bodyParser = require('body-parser');
const mysql = require('mysql');
const bookRoutes = require('./api/routes/books');
const entryRoutes = require('./api/routes/entries');
const connection = mysql.createConnection({
host: 'localhost',
user: 'rlreader',
password: process.env.MYSQL_DB_PW,
database: 'books'
});
app.use(morgan('dev'));
app.use(bodyParser.urlencoded({extended: false}));
app.use(bodyParser.json());
app.use((req, res, next) => {
res.header('Access-Control-Allow-Origin', '*');
res.header('Access-Control-Allow-Headers', 'Origin, X-Requested-With, Content-Type, Accept, Authorization');
if (req.method === 'OPTIONS') {
res.header('Access-Control-Allow-Methods', 'GET');
return res.status(200).json({});
}
next();
});
// Routes which should handle requests
app.use('/books', bookRoutes);
app.use('/entries', entryRoutes);
app.use((req, res, next) => { //request, response, next
const error = new Error('Not found');
error.status = 404;
next(error);
});
app.use((error, req, res, next) => {
res.status(error.status || 500);
res.json({
error: {
message: error.message
}
});
});
module.exports = app;
books.js
const express = require('express');
const router = express.Router();
const axios = require('axios');
//do I import something for mysql here?
router.get('/', (req, res, next) => {
axios.get('/').then(docs => {
res.status(200).json({
"hello": "hi" //want to query MySQL database here
})
}).catch(err => {
res.status(500).json({
error: err
});
})
});
module.exports = router;
Any help would be appreciated. For starters, how do I get const connection from app.js to books.js?
I moved the code connecting to the MySQL database to a separate file and included that:
const con = require('../../db');
Next, I had to properly return the response:
router.get('/', (req, res, next) => {
let responseData = axios.get('/').then(docs => {
const sql = "SELECT title, id FROM books";
con.query(sql, function (err, result) {
if (err) {
console.log("error happened");
}
return res.status(200).json(result);
});
}).catch(err => {
res.status(500).json({
error: err
});
});
});
Related
On the client side, I have an application based on threejs an d javascript. I want to send data to the server written in express using fetch. Unfortunately, the server does not receive the data and the browser also gives an error:
Uncaught (in promise) TypeError: NetworkError when attempting to fetch resource.
Application:
this.username = prompt("Username:");
const body = JSON.stringify({ username: this.username });
fetch("http://localhost:3000/addUser", { method: "POST", body })
.then((response) => response.json())
.then(
(data) => (
console.log(data), (this.aktualny_album_piosenki = data.files)
)
);
Server:
var express = require("express")
var app = express()
const PORT = 3000;
var path = require("path");
app.use(express.static('dist'));
var bodyParser = require("body-parser");
app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json());
var cors = require('cors');
app.use(cors());
app.post("/addUser", function (req, res) {
console.log(req.body)
})
I might be wrong but maybe try... (very bottom of your main server file)
app.listen((PORT) => {
console.log(`app is listening on port ${PORT}`);
})
is required maybe? I have this chunk of code in every project of my own so maybe that could fix the server not recognizing the api request
express documentation on app listen
heres what I use typically... this is a boilerplate for every one of my projects
const express = require("express");
const app = express();
const connectDB = require("./config/db.js");
const router = express.Router();
const config = require("config");
// init middleware
const bodyParser = require('body-parser');
const cors = require("cors");
const mongoDB = require("./config/db.js");
const path = require("path");
const http = require("http");
const server = http.createServer(app);
const io = require('socket.io')(server, {
cors: {
origin: '*',
}
});
const xss = require('xss-clean');
const helmet = require("helmet");
const mongoSanitize = require('express-mongo-sanitize');
const rateLimit = require("express-rate-limit");
const PORT = process.env.PORT || 5000;
mongoDB();
app.options('*', cors());
app.use('*', cors());
app.use(cors());
const limitSize = (fn) => {
return (req, res, next) => {
if (req.path === '/upload/profile/pic/video') {
fn(req, res, next);
} else {
next();
}
}
}
const limiter = rateLimit({
max: 100,// max requests
windowMs: 60 * 60 * 1000 * 1000, // remove the last 1000 for production
message: 'Too many requests' // message to send
});
app.use(xss());
app.use(helmet());
app.use(mongoSanitize());
app.use(limiter);
// app.use routes go here... e.g. app.use("/login", require("./routes/file.js");
app.get('*', function(req, res) {
res.sendFile(__dirname, './client/public/index.html')
})
app.get('*', cors(), function(_, res) {
res.sendFile(__dirname, './client/build/index.html'), function(err) {
if (err) {
res.status(500).send(err)
};
};
});
app.get('/*', cors(), function(_, res) {
res.sendFile(__dirname, './client/build/index.html'), function(err) {
if (err) {
res.status(500).send(err)
};
};
});
app.use(function(req, res, next) {
res.header("Access-Control-Allow-Origin", '*');
res.header("Access-Control-Allow-Credentials", true);
res.header('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE,OPTIONS');
res.header("Access-Control-Allow-Headers", 'Origin,X-Requested-With,Content-Type,Accept,content-type,application/json');
next();
});
if (process.env.NODE_ENV === "production") {
// Express will serve up production files
app.use(express.static("client/build"));
// serve up index.html file if it doenst recognize the route
app.get('*', cors(), function(_, res) {
res.sendFile(__dirname, './client/build/index.html'), function(err) {
if (err) {
res.status(500).send(err)
}
}
})
app.get('/*', cors(), function(_, res) {
res.sendFile(path.join(__dirname, './client/build/index.html'), function(err) {
if (err) {
res.status(500).send(err)
}
})
})
};
io.on("connection", socket => {
console.log("New client connected");
socket.on("disconnect", () => console.log("Client disconnected"));
});
server.listen(PORT, () => {
console.log(`Server listening on port ${PORT}!`);
});
client-side fetch request looks good to me its prob a server/express.JS thing but like i said i may be wrong but worth trying
When I make a post request to the /login endpoint in postman it works fine and returns all the information. However when I try to navigate to the end point in the url the route returns unfound. In the console I get GET http://localhost:5000/login 404 (Not Found). Why is the console returning for a get request? If I try to call the post request in axios I get xhr.js:177 POST http://localhost:3000/login 404 (Not Found).
app.js
require("dotenv").config();
const express = require('express');
const morgan = require('morgan');
const bodyParser = require('body-parser');
const router = express.Router();
const cors = require('cors');
const app = express();
app.use(cors())
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({
extended: true
}));
const mongoose = require('mongoose');
const connection = "password"
mongoose.connect(connection, {
useNewUrlParser: true,
useCreateIndex: true,
useUnifiedTopology: true
})
const clientRoutes = require('./routes/clientRoutes');
const traderRoutes = require('./routes/traderRoutes');
const loginRoute = require('./routes/loginRoute')
app.use('/', clientRoutes, traderRoutes, loginRoute);
// setup a friendly greeting for the root route
app.get('/', (req, res) => {
res.json({
message: 'Welcome to the REST API for Pave!',
});
});
// send 404 if no other route matched
app.use((req, res) => {
res.status(404).json({
message: 'Route Not Found',
});
});
// setup a global error handler
app.use((err, req, res, next) => {
if (enableGlobalErrorLogging) {
console.error(`Global error handler: ${JSON.stringify(err.stack)}`);
}
res.status(err.status || 500).json({
message: err.message,
error: {},
});
});
app.listen(5000, () => console.log('Listening on port 5000!'))
loginRoute.js
require("dotenv").config();
const express = require("express");
const router = express.Router();
const jwt = require("jsonwebtoken");
const bcryptjs = require("bcryptjs");
const Client = require("../models/clientSchema");
const Trader = require("../models/traderSchema");
function asyncHandler(callback) {
return async (req, res, next) => {
try {
await callback(req, res, next);
} catch (error) {
next(error);
console.log(error);
}
};
}
router.post('/login', asyncHandler(async (req, res, next) => {
let user = req.body;
const trader = await Trader.findOne({ emailAddress: req.body.emailAddress })
if (user && trader) {
console.log(trader)
let traderAuthenticated = await bcryptjs.compareSync(user.password, trader.password);
console.log(traderAuthenticated)
if (traderAuthenticated) {
console.log('Trader match')
const accessToken = jwt.sign(trader.toJSON(), process.env.ACCESS_TOKEN_SECRET)
res.location('/trader');
res.json({
trader: trader,
accessToken: accessToken
}).end();
} else {
res.status(403).send({ error: 'Login failed: Please try again'}).end();
}
} else if (user && !trader) {
const client = await Client.findOne({emailAddress: req.body.emailAddress})
console.log(client)
let clientAuthenticated = await bcryptjs.compareSync(user.password, client.password);
console.log(clientAuthenticated)
if (clientAuthenticated) {
console.log('Client match')
const accessToken = jwt.sign(client.toJSON(), process.env.ACCESS_TOKEN_SECRET)
res.location('/client');
res.json({
client: client,
accessToken: accessToken
});
} else {
res.status(403).send({ error: 'Login failed: Please try again'}).end();
}
} else {
res.status(403).send({ error: 'Login failed: Please try again'}).end();
}
})
);
module.exports = router;
You set POSTMAN to make a POST request, right? When you enter a url in the browser, that causes a GET request - and you have no route to manage this that I can see, but for the default Not found.
you are calling with axios with wrong port no. it should, POST method http://localhost:5000/login as your application is running on port 5000.
but you are calling, POST http://localhost:3000/login
I used postman to post to register a user with "http://localhost:3000/register?name=USER1&email=user1#testsite.com&password=pass1"
and seems like it doesn't get routed correctly. What could be the problem?
Errors: Postman shows Cannot POST /register.
Other than that, no errors, server runs ok in port 3000
App.js
require('dotenv').config();
const passport = require('passport');
require("./app_api/passport")
const path = require("path");
const express = require("express");
const bodyParser = require("body-parser");
const mongoose = require("mongoose");
const app = express();
const userRoutes = require("./app_api/routes/index");
mongoose
.connect(
"mongodb://127.0.0.1:27017"
, {useNewUrlParser: true, useUnifiedTopology: true, useCreateIndex:true}
) .then(() => {
console.log("Connected to database!");
})
.catch(() => {
console.log("Connection failed!");
});
app.use(passport.initialize());
app.use((req, res, next) => {
res.setHeader("Access-Control-Allow-Origin", "*");
res.setHeader(
"Access-Control-Allow-Headers",
"Origin, X-Requested-With, Content-Type, Accept, Authorization"
);
res.setHeader(
"Access-Control-Allow-Methods",
"GET, POST, PATCH, PUT, DELETE, OPTIONS"
);
next();
});
app.use("/register", userRoutes);
module.exports = app;
./routes/index.js
const express = require("express");
const ctrlAuth = require("../../controllers/authentication");
const router = express.Router();
router.post('/register', function(req, res){ctrlAuth.register});
router.post('/login', function(req, res){ctrlAuth.login});
module.exports = router;
./controllers/authentication.js
const passport = require('passport');
const mongoose = require('mongoose');
const User = require('../schema/user');
const register = (req, res) => {
if (!req.body.name || !req.body.email || !req.body.password) {
return res
.status(400)
.json({"message": "All fields required"});
const user = new User();
user.name = req.body.name;
user.email = req.body.email;
user.setPassword(req.body.password);
user.save((err) => {
if (err) {
res
.status(404)
.json(err);
} else {
const token = user.generateJwt();
res
.status(200)
.json({
token
,message: "User created!"
});
}
});
};
module.exports = {
register
};
const login = (req, res) => {
if (!req.body.email || !req.body.password) {
return res
.status(400)
.json({"message": "All fields required"});
}
passport.authenticate('local', (err, user, info) => {
let token;
if (err) {
return res
.status(404)
.json(err);
}
if (user) {
token = user.generateJwt();
res
.status(200)
.json({token});
} else {
res
.status(401)
.json(info);
}
})(req, res);
};
module.exports = {
login
};
change ./controllers/authentication.js exports functions like this
const passport = require("passport");
const mongoose = require("mongoose");
const User = require("../schema/user");
const register = (req, res) => {
if (!req.body.name || !req.body.email || !req.body.password) {
return res.status(400).json({ message: "All fields required" });
}
const user = new User();
user.name = req.body.name;
user.email = req.body.email;
user.setPassword(req.body.password);
user.save((err) => {
if (err) {
res.status(404).json(err);
} else {
const token = user.generateJwt();
res.status(200).json({
token,
message: "User created!",
});
}
});
};
const login = (req, res) => {
if (!req.body.email || !req.body.password) {
return res.status(400).json({ message: "All fields required" });
}
passport.authenticate("local", (err, user, info) => {
let token;
if (err) {
return res.status(404).json(err);
}
if (user) {
token = user.generateJwt();
res.status(200).json({ token });
} else {
res.status(401).json(info);
}
})(req, res);
};
exports.register = register;
exports.login = login;
and change your App.js, remove /register from route
require('dotenv').config();
const passport = require('passport');
require("./app_api/passport")
const path = require("path");
const express = require("express");
const bodyParser = require("body-parser");
const mongoose = require("mongoose");
const app = express();
const userRoutes = require("./app_api/routes/index");
mongoose
.connect(
"mongodb://127.0.0.1:27017"
, {useNewUrlParser: true, useUnifiedTopology: true, useCreateIndex:true}
) .then(() => {
console.log("Connected to database!");
})
.catch(() => {
console.log("Connection failed!");
});
app.use(passport.initialize());
app.use((req, res, next) => {
res.setHeader("Access-Control-Allow-Origin", "*");
res.setHeader(
"Access-Control-Allow-Headers",
"Origin, X-Requested-With, Content-Type, Accept, Authorization"
);
res.setHeader(
"Access-Control-Allow-Methods",
"GET, POST, PATCH, PUT, DELETE, OPTIONS"
);
next();
});
app.use("/", userRoutes);
module.exports = app;
change router like this :
const express = require("express");
const ctrlAuth = require("../../controllers/authentication");
const router = express.Router();
router.post('/register', ctrlAuth.register);
router.post('/login', ctrlAuth.login);
module.exports = router;
I wrote a small node.js server with a login system and I am trying to protect my routes. I have created the middleware that should check authentication on each protected route, but it seems that I am not sending the JWT token correctly, because every time I log in I get the Authentication failed message. How can I send the JWT token correctly and log in if the password and username are correct? Here is my Node.js server:
const express = require('express');
const app = express();
const bodyParser = require('body-parser');
const cors = require('cors');
const mongoose = require('mongoose');
require('dotenv').config();
const PORT = process.env.PORT || 1337;
const jwt = require('jsonwebtoken');
const checkAuth = require('./middleware/check-auth.js')
let Post = require('./models/post.model.js');
app.use(cors());
app.use("/assets", express.static(__dirname + "/assets"));
app.use(bodyParser.urlencoded({ extended: true }));
app.set('view-engine', 'ejs');
app.get('/', (req, res) => {
res.render('index.ejs');
});
app.post('/', (req, res) => {
let username = req.body.username;
let password = req.body.password;
if (username !== process.env.USER_NAME && password !== process.env.USER_PASSWORD) {
res.json('Invalid credentials');
} else {
const token = jwt.sign({
username: username,
}, process.env.SECRET_KEY, {
expiresIn: '1h'
});
res.redirect(`/dashboard?token=${token}`);
}
});
app.get('/dashboard', checkAuth, (req, res) => {
res.render('dashboard.ejs');
});
app.get('/dashboard/createPost', checkAuth, (req, res) => {
res.render('post.ejs');
});
app.post('/dashboard/createPost', async (req, res) => {
let collection = connection.collection(process.env.POSTS_WITH_TAGS);
res.setHeader('Content-Type', 'application/json');
let post = new Post(req.body);
collection.insertOne(post)
.then(post => {
res.redirect('/dashboard')
})
.catch(err => {
res.status(400).send(err);
});
});
app.listen(PORT);
and here is my check-auth middleware:
const jwt = require('jsonwebtoken');
module.exports = (req, res, next) => {
try {
const token = req.headers.authorization.split(' ')[1];
console.log(token);
const decoded = jwt.verify(token, process.env.SECRET_KEY, null);
req.body.decoded = decoded;
console.log(req.body.decoded);
} catch (error) {
return res.status(401).json({
message: 'Authentication failed'
});
}
next();
};
Use Javascript fetch API for sending JWT token as header authorization
fetch('backend_domain/dashboard', {
method: 'get',
headers: {
Authorization: JWT_Token
}
}).then(data => {..your operation here..})
Reference: fetch_mdn for better understanding of fetch API
I think the problem here is that you are getting an empty object in req.body when you try to pass it as a json string in postman. I would recommend either
pass your credentials in x-www-form-urlencoded tag in postman or
Using express.Router() and creating different files for routes
In your index.js file write:
app.use('/', require('./routes.js'))
And create a file with name routes.js and put your routes as this:
const express = require('express');
const router = express.Router();
router.post('/', (req, res) => {
let username = req.body.username;
let password = req.body.password;
console.log(req.body);
if (username !== process.env.USER_NAME && password !== process.env.USER_PASSWORD) {
res.json('Invalid credentials');
} else {
const token = jwt.sign({
username: username
}, process.env.SECRET_KEY, {
expiresIn: 3600
});
return res.send({token});
}
});
module.exports = router;
I got back on a project that I didn't touch for a while and I get this error.
MongoNetworkError: failed to connect to server [cluster0-shard-00-01-ntrwp.mongodb.net:27017] on first connect [MongoNetworkError: connection 5 to cluster0-shard-00-01-ntrwp.mongodb.net:27017 closed
I checked the connection network access and allowed everyone I checked twice the mongoose.connect CREDENTIAL and I don't see why it keeps sending me this error. I also reinstall npm mongoose.
const fs = require("fs");
const path = require("path");
const express = require("express");
const bodyParser = require("body-parser");
const mongoose = require("mongoose");
const placesRoutes = require("./routes/places-routes");
const usersRoutes = require("./routes/users-routes");
const HttpError = require("./models/http-error");
const app = express();
app.use(bodyParser.json());
app.use("/uploads/images", express.static(path.join("uploads", "images")));
app.use((req, res, next) => {
res.setHeader("Access-Control-Allow-Origin", "*");
res.setHeader(
"Access-Control-Allow-Headers",
"Origin, X-Requested-With, Content-Type, Accept, Authorization"
);
res.setHeader("Access-Control-Allow-Methods", "GET, POST, PATCH, DELETE");
next();
});
app.use("/api/places", placesRoutes);
app.use("/api/users", usersRoutes);
app.use((req, res, next) => {
const error = new HttpError("Could not find this route.", 404);
throw error;
});
app.use((error, req, res, next) => {
if (req.file) {
fs.unlink(req.file.path, (err) => {
console.log(err);
});
}
if (res.headerSent) {
return next(error);
}
res.status(error.code || 500);
res.json({ message: error.message || "An unknown error occurred!" });
});
mongoose
.connect(
`mongodb+srv://XXXX:XXXX#cluster0-ntrwp.mongodb.net/XXXX?retryWrites=true&w=majority`
)
.then(() => {
app.listen(5000);
})
.catch((err) => {
console.log(err);
});