I have a node.js server combined with a react.js frontend. I've a form that requires users to upload files to a AWS S3 bucket. I'm using Multer.js to handle the file upload. I've set the default upload size to a max of 10mb. While there is absolutely no problem in uploading files as long as the file size below 10mb when testing using localhost. However, when I try to do the same from my Nginx Web Server, I get a '413 Error : Request entity too large' while trying to upload anything that is above 1mb. I've tried to follow the solutions here and here but to no luck.
I don't any error output except the 413 Error that my frontend app catches.
Here's the code to my express loader ( referencing this because I've tried the solutions mentioned above on these lines of code. )
const express = require("express");
const bodyParser = require("body-parser");
const cookieParser = require("cookie-parser");
const helmet = require("helmet");
const cors = require("cors");
const morgan = require("morgan");
const path = require("path");
const appRoot = require("app-root-path");
const loadRoutes = require("../api");
const logger = require("./logger");
const { userRoles } = require("../utils/consts");
const authService = require("../services/AuthService");
const expressLoader = (app) => {
app.use(cors());
app.use(express.static(path.join(appRoot.path, "public", "users")));
//app.use(express.static(path.join(appRoot.path, "public", "admin")));
// ATTACH IP ADDRESS TO EACH REQUEST
app.use((req, res, next) => {
req.ipAddress = req.headers["x-forwarded-for"] || req.connection.remoteAddress;
return next();
});
// Extract token from header
app.use((req, res, next) => {
const token = req.headers["authorization"] ? req.header("authorization").split(" ")[1] : null;
if (token) {
req.token = token;
}
return next();
});
// Verify token
app.use(async (req, res, next) => {
if (req.token) {
const decode = await authService.verifyAuthToken(req.token);
console.log(decode);
if (!decode.tokenValid) {
logger.error(`[INVALID JWT ${req.path}] ip: ${req.ipAddress}`);
logger.error(decode.err);
req.isAuth = false;
return next();
} else {
req.isAuth = true;
req.decode = decode.data;
return next();
}
}
return next();
});
// Check if is admin
app.use((req, res, next) => {
const roleId = req.decode ? req.decode.role_id : null;
if (req.isAuth && (roleId === userRoles.SYSOP || roleId === userRoles.ADMIN)) {
req.isAdmin = true;
return next();
}
return next();
});
app.use(morgan("combined", { stream: logger.stream }));
app.use(helmet());
app.use(bodyParser.json({ limit: '50mb' }));
app.use(bodyParser.urlencoded({ limit: '50mb', extended: true }));
//app.use(cookieParser(process.env.SCOOK_SECRET));
// app.enable("trust proxy"); TO BE ENABLED FOR NGINX
// LOAD API
app.use(process.env.API_PREFIX, loadRoutes());
// app.use("/admin", (req, res, next) => {
// logger.info(`[ADMIN ROUTE ACCESSED FROM ${ req.ip }]`);
// return res.sendFile(path.join(appRoot.path + "/public/admin/index.html"));
// });
app.get("*", (req, res, next) => {
return res.sendFile(path.join(appRoot.path + "/public/users/index.html"));
});
}
module.exports = expressLoader;
Any help would be appreciated, thank you!
Related
I created a api route named "/add" that renders a file named "additional-user-info" with crsf token and it works fine
app.js
const express = require("express");
require("dotenv").config();
const mongoose = require("mongoose");
const authRoutes = require("./routes/authRoutes");
const cookieParser = require("cookie-parser");
var csrf = require("csurf");
var csrfProtection = csrf({ cookie: true });
const {
requireAuth,
checkUser,
displayallusers,
deleteUser,
searchuser,
isAdmin,
} = require("./middleware/authMiddleware");
const mongoSantize = require("express-mongo-sanitize");
const xss = require("xss-clean");
const app = express();
// middleware
app.disable("x-powered-by");
app.use(express.static("public"));
app.use(mongoSantize());
app.use(xss());
app.use(express.json());
app.use(cookieParser());
//handling wrong invlid json syntax
app.use((err, req, res, next) => {
if (err instanceof SyntaxError && err.status === 400 && "body" in err) {
//console.error(err);
return res.status(400).send("Invalid Json formatting"); // Bad request
}
});
// view engine
app.set("view engine", "ejs");
// database connection
const mongoUsername = process.env.MONGO_USERNAME;
const mongoPassword = process.env.MONGO_PASSWORD;
const dbURI =
"mongodb+srv://" +
mongoUsername +
":" +
mongoPassword +
"#boioboi/real-auth?retryWrites=true&w=majority";
mongoose
.connect(dbURI, {
useNewUrlParser: true,
useUnifiedTopology: true,
useCreateIndex: true,
})
.then((result) => app.listen(3000))
.catch((err) => console.log(err));
// routes
app.get("*", checkUser);
app.get("/add", csrfProtection, (req, res) => {
console.log("zeeeeeeeee");
console.log(req.csrfToken());
res.render("additional-user-info", { csrfToken: req.csrfToken() });
});
app.get("/", (req, res) => res.render("home"));
app.get("/smoothies", requireAuth, (req, res) => res.render("smoothies"));
app.use(authRoutes);
Website has a functionality that if a user creates an account or logins into his account and has certian database fields empty website would render same "additional-user-info" page to get his info
This is a function that checks if a user is valid or not and renders "additional-user-info" page if certain fields are empty
authMiddleware
const checkUser = (req, res, next) => {
const token = req.cookies.jwt;
if (token) {
jwt.verify(token, jwt_secret, async (err, decodedtoken) => {
if (err) {
console.log(err.message);
res.locals.user = null;
next();
} else {
console.log(decodedtoken);
let user = await User.findById(decodedtoken.id);
res.locals.user = user;
if (
(user.additionalinfo.fullname == "") |
(user.additionalinfo.address == "") |
(user.additionalinfo.city == "") |
(user.additionalinfo.district == "") |
(user.additionalinfo.propertytype == "") |
(user.additionalinfo.adharcard == "") |
(user.additionalinfo.pancard == "")
) {
return res.render("additional-user-info"); //crsf-token is not defined error here
}
next();
}
});
} else {
res.locals.user = null;
next();
}
};
But when it renders "additional-user-info" page from checkUser() function it gives error saying "csrfToken is not defined". How should i fix this issue?
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
So I'm working with next.js and a custom server (express.js). I have some middlewares, (f.ex. const attachUser) which I'd like to use in my API endpoints. But for some reason, I am unable to use app.use.
The following code only works, when I don't use app.use(attachUser) and add attachUser to every endpoint manually.
require("dotenv").config();
const express = require("express");
const next = require("next");
const bodyParser = require("body-parser");
const cors = require("cors");
//next.js configuration
const dev = process.env.NODE_DEV !== "production";
const nextApp = next({
dev
});
const port = 3000;
const handle = nextApp.getRequestHandler();
nextApp.prepare().then(() => {
const app = express();
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({
extended: false
}));
app.use(cors());
const attachUser = (req, res, next) => {
const token = req.cookies["token"];
if (!token) {
return res.status(401).json({
message: "Authentication invalid"
});
}
const decodedToken = jwtDecode(token);
if (!decodedToken) {
return res.status(401).json({
message: "There was a problem authorizing the request",
});
} else {
req.user = decodedToken;
next();
}
};
//app.use(attachUser)
app.get(
"/api/savedItems",
attachUser, //delete when app.use(attachUser) is used
async(req, res) => {
try {
//logic
return res.json(itemData);
} catch (err) {
return res.status(400).json({
error: err
});
}
});
Can someone tell me what I'm doing wrong?
Btw, this is my first project. Any suggestions to improve code are appreciated! Thanks a lot!
You can't write code between a "try {}" and a "catch{}" and aditionally a useless ";" after "try{}". You can use a JS lint tool for checking code
Attempting to use Axios.get method to get ':id'
S̶e̶r̶v̶e̶r̶ ̶i̶s̶ ̶r̶e̶s̶p̶o̶n̶d̶i̶n̶g̶ ̶w̶i̶t̶h̶ ̶a̶ ̶4̶0̶4̶
Currently I am unable to set the state of the component. I get an empty object
I've tried adjusting the controller parameters but cannot seem to figure it out
loadProfile() {
axios.get('http://localhost:3000/api/companies/' + this.props.match.params.id)
.then(res => {
if (!res) {
console.log("404 error, axios cannot get response");
} else {
console.log(res.data);
this.setState({ company: res.data });
}
});
express api route
companyRoutes.route('/:id').get(company_controller.company_id_get);
express controller
exports.company_id_get = (req, res) => {
const id = req.params.id;
Company.findById( id, (company, err) => {
if(err) {
console.log("404 error", err);
}
else {
res.json(company);
}
})
}
Server Side Code
'use strict';
const express = require('express');
const mongoose = require('mongoose');
const bodyParser = require('body-parser');
const cors = require('cors')
const passport = require('passport');
const app = express();
const users = require('./routes/api/users');
const companyRoute = require('./routes/api/companies');
app.use(express.static("static"));
//Bodyparser middleware
app.use(cors());
app.use(
bodyParser.urlencoded({
extended: false
})
);
app.use(bodyParser.json());
// DB configuration
const db = require("./config.scripts/mongoKey").mongoURI;
// Connect to MonngoDB
mongoose.connect(
db, { useNewUrlParser: true }
)
.then((db) => console.log('MongoDB succesfully connected'))
.catch(err => console.log(err));
//Passport middleware
app.use(passport.initialize());
//Passport config
require('./config.scripts/passport.js')(passport);
//Routes
app.use('/api/users', users);
app.use('/api/companies', companyRoute);
//Redirect any server request back to index.html: To deal with CRS
app.get('/', function(req, res, next){
res.sendFile(path.join(__dirname, '../client', 'index.html'));
})
//Hostname and Port
//const hostname = '127.0.0.1';
const port = 3000;
app.listen(port, () => {
console.log(`Backend server is running at http://localhost:${port}/`);
});
An error that is showing up in the console/network and postman. It looks like the http.get request is being stalled
Seems you forgot a / in your route http:/localhost:3000/api/companies/.... Change it to http://... and that should fix your issue.