req.cookies is null and I don't know why - node.js

I've looked at a few previous stack overflow posts but can't figure out why this is happening.
I have included cookie parser before all my routes and the cookie is in the browser. For some reason I just can't access it.
const cookieParser = require("cookie-parser");
const cors = require("cors");
const AppError = require("./utils/appError");
const globalErrorHandler = require("./controllers/errorController");
const dishRouter = require("./routes/dishRoutes");
const userRouter = require("./routes/userRoutes");
const orderRouter = require("./routes/orderRoutes");
const imageRouter = require("./routes/imageRouter");
const app = express();
app.use(cookieParser());
app.enable("trust proxy");
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
app.use(cors());
app.options("*", cors());
ROUTES...
Here is how I am accessing the req.cookies
First I do an axios call
axios({
method: "patch",
url: `http://localhost:8080/api/v1/users/me`,
data: this.state,
})
Then it goes through this middleware
router
.route("/me")
.patch(authController.protect, userController.updateProfile)
In authController.protect I do the following
try {
//1) Getting token and check if it exists.
let token;
if (
//POSTMAN
req.headers.authorization &&
req.headers.authorization.startsWith("Bearer")
) {
token = req.headers.authorization.split(" ")[1];
} else if (req.cookies.jwt) {
token = req.cookies.jwt;
}
console.log(`TOKEN: ${token}`);
console.log(req.cookies);
The console.log right above gives null.

I faced a similar issue with my code where I was getting null when checking req.cookies. I used express for my node.js files and I followed the explanations from the following links:
http://expressjs.com/en/resources/middleware/cors.html
https://developers.google.com/web/updates/2015/03/introduction-to-fetch
So from server side I added configuration to cors() and set credentials: true and on client side from my fetch() request I added credentials: 'include' and this gave me access to the cookies on my browser. My fetch() request was making use of the PUT method.

Related

How can I proxy form data using http-proxy-middleware?

I created a proxy on firebase using http-proxy-middleware.
It works on GET requests but does not pass the data I send via body in POST requests. I did some research and added the "onProxyReq" method to the options. This way it works when I send json body, but not when I send form data.
const functions = require("firebase-functions");
const express = require("express");
var bodyParser = require("body-parser");
const {
createProxyMiddleware,
fixRequestBody,
} = require("http-proxy-middleware");
const app = express();
app.use(bodyParser.urlencoded({ extended: true }));
var restream = function (proxyReq, req, res, options) {
if (req.body) {
let bodyData = JSON.stringify(req.body);
proxyReq.setHeader("Content-Type", "application/json");
proxyReq.setHeader("Content-Length", Buffer.byteLength(bodyData));
proxyReq.write(bodyData);
}
};
app.use(
"/",
createProxyMiddleware({
target: "http://IPADDRESS:8080/api",
changeOrigin: true,
onProxyReq: restream,
bodyParser: false,
})
);
exports.api = functions.https.onRequest(app);
This code works with json body.
Changing "application/json" to "multipart/form-data" doesn't work.
All I want is to redirect the JWT token in the header and the FormData in the body.
What should be the best way for this?

Cannot get Stored Cookies from browser in Express Js

Ive set user cookie as a jwt token in the browser and it is setted up successfully but when I try to get that cookie using req.cookies it gives me undefined and [object: null prototype] {}. Heres my code
exports.isAuthenticated = asyncErrorHandler(async (req, res, next) => {
//fetching the jwt token from the cookie
const { token } = req.cookies;
console.log(req.cookies);
if (!token) return next(new ErrorHandler("plz log in first ", 400));
//verifying the given token matches the jwt stored token
const decodedData = jwt.verify(token, process.env.JWT_SECRET);
req.user = await userModel.findById(decodedData.id);
next();
});
this is my express app.js file
const express = require("express");
const errorMiddleware = require("./middleware/error");
const cookieParser = require("cookie-parser");
const bodyparser = require("body-parser");
const fileupload = require("express-fileupload");
const cors = require("cors");
const app = express();
app.use(cookieParser());
app.use(express.json());
app.use(bodyparser.urlencoded({ extended: true }));
app.use(fileupload());
app.use(
cors({
credentials: true,
origin: "http://127.0.0.1:5173",
optionsSuccessStatus: 200,
})
);
// Route Imports
const productRoutes = require("./routes/productRoutes");
const userRoutes = require("./routes/userRoutes");
const orderRoutes = require("./routes/orderRoute");
const bodyParser = require("body-parser");
app.use("/api/v1", productRoutes);
app.use("/api/v1/user", userRoutes);
app.use("/api/v1", orderRoutes);
//error HAndler Middleware
app.use(errorMiddleware);
module.exports = app;
Ive tried cookie-parseer and also had cors in my express app file. ive set the cookie key as token
the req.cookies isn't the right way to get cookies
If you want to get cookies it is in the header so you must get cookies from header from the request like this :
console.log(req.headers.cookie)

504 Gateway Timeout issue in expressjs while uploading file

Hi i am facing CORS issue in expressjs and nuxtjs while uploading files in production mode. things works fine on localhost but after i deploy to digital ocean, only one route where i upload file doesn't work.
here are the codes so far
this is app.js
const express = require('express');
const helmet = require('helmet');
const xss = require('xss-clean');
const mongoSanitize = require('express-mongo-sanitize');
const compression = require('compression');
const cors = require('cors');
const passport = require('passport');
const httpStatus = require('http-status');
const config = require('./config/config');
const morgan = require('./config/morgan');
const { jwtStrategy } = require('./config/passport');
const { authLimiter } = require('./middlewares/rateLimiter');
const routes = require('./routes/v1');
const { errorConverter, errorHandler } = require('./middlewares/error');
const ApiError = require('./utils/ApiError');
const app = express();
if (config.env !== 'test') {
app.use(morgan.successHandler);
app.use(morgan.errorHandler);
}
// set security HTTP headers
app.use(helmet());
// parse json request body
app.use(express.json());
// parse urlencoded request body
app.use(express.urlencoded({ extended: true }));
// sanitize request data
app.use(xss());
app.use(mongoSanitize());
// gzip compression
app.use(compression());
// enable cors
app.use(cors());
app.options('*', cors());
// jwt authentication
app.use(passport.initialize());
passport.use('jwt', jwtStrategy);
// limit repeated failed requests to auth endpoints
if (config.env === 'production') {
app.use('/v1/auth', authLimiter);
}
// v1 api routes
app.use('/v1', routes);
// send back a 404 error for any unknown api request
app.use((req, res, next) => {
next(new ApiError(httpStatus.NOT_FOUND, 'Not found'));
});
// convert error to ApiError, if needed
app.use(errorConverter);
// handle error
app.use(errorHandler);
module.exports = app;
this is upload.route.js inside routes folder
const express = require('express');
const uploadController = require('../../controllers/uploads.controller')
const router = express.Router();
router.post('/image', uploadController.setProductImages)
router.post('/image/activity', uploadController.uploadActivityImage)
module.exports = router;
this is index.js inside routes folder
const express = require('express');
const uploadRoute = require('./upload.route');
const config = require('../../config/config');
const router = express.Router();
const defaultRoutes = [
{
path: '/uploads',
route: uploadRoute
}
];
defaultRoutes.forEach((route) => {
router.use(route.path, route.route);
});
module.exports = router;
this is the error i am getting when i upload files.
cross-Origin Request Blocked: The Same Origin Policy disallows reading
the remote resource at
https://v1api.thetripclub.com/v1/uploads/image/activity. (Reason: CORS
header ‘Access-Control-Allow-Origin’ missing). Status code: 504.
XHRPOSThttps://***.*******.com/v1/uploads/image/activity
CORS Missing Allow Origin

Node JS - can't send data from Postman

I solved it, it was a problem with req.body empty
==
I trying to test this route but the data I send is not received. I tried Postman and a VC extension, same problem.
I send this data and I expected it to be available in req.body
{
"username": "OPK"
}
http://prntscr.com/tn722o
And header is set correctly to application/json
http://prntscr.com/tn74on
I do however get this error when I try rest client extension:
Header name must be a valid HTTP token ["{"]
app.js
const express = require("express")
const app = express()
const userRouter = require("./routes/userRoute")
const dotenv = require("dotenv")
dotenv.config()
mongoose.connect(process.env.CONNECTIONSTRING, {
useUnifiedTopology: true,
useNewUrlParser: true,
})
app.use(express.urlencoded({ extended: false }))
// app.use(express.json())
app.use("/user", userRouter)
app.listen(process.env.PORT)
useRoute.js:
const express = require("express")
const router = express.Router()
const userController = require("../controllers/userController")
router.post("/signup", userController.signUp)
module.exports = router
userController.js
const mongoose = require("mongoose")
const userModel = require("../models/userModel")
exports.signUp = (req, res) => {
const { username, email, password, passwordAgain } = req.body
return res.status(422).json({ username: username })
}
I suggest you to update your Postman to the latest version and install it as a separate application, not as extension for Chrome.
To check if your server method works in general you can send this request via curl:
curl --location --request POST 'http://localhost:5000/user/signup' \
--header 'Content-Type: application/json' \
--data-raw '{"username": "OPK"}'
You might need to use body-parser with Express.js to handle POST requests, that is if you're not using express#4.16.0 or greater.
npm instal --save body-parser
const express = require('express')
const bodyParser = require('body-parser')
const app = express()
// parse application/x-www-form-urlencoded
app.use(bodyParser.urlencoded({ extended: false }))
// parse application/json
app.use(bodyParser.json())

ExpressJs request body is empty

I have an express app at localhost:5000 and a react app at localhost:3000.
I am calling it via
fetch(`${backendUrl}/charge`, {
method: "POST",
mode: "no-cors",
headers: {
"Content-Type": "application/json"
},
body: {
stripeToken: token,
chargeAmount: this.state.donationAmount
}
})
And responding with
function route(req, res) {
console.log(req.body);
}
Server should be properly configured to work with CORS, but the body is still empty.
//configure env variables
require("dotenv").config();
//import packages
var express = require("express");
var bodyParser = require("body-parser");
var cors = require("cors");
//import route functions
const StripeRoute = require("./StripeRoute");
//setup app
const app = express();
const port = process.env.PORT || 5000;
//setup bodyparser
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
//Setup CORS
app.use(cors());
app.options("*", cors()); // include before other routes
//Connect functions to API routes
app.post("/charge", StripeRoute);
module.exports = app;
According to the documentation, the body option should be one of a few specific types, Object not being one of them.
Try using a JSON string:
body: JSON.stringify({
stripeToken: token,
chargeAmount: this.state.donationAmount
})
EDIT: because you're using no-cors, you can't set Content-Type application/json. Instead, you need to generate a URL-encoded string and set Content-Type to application/x-www-form-urlencoded (because no-cors will only work using "simple headers", as explained here and further).

Resources