i'm a beginner in node.js and trying to redirect a post request. here is the code snippet
const mongoose = require('mongoose');
const passport = require('passport');
const router = require('express').Router();
const auth = require('../auth');
const Users = mongoose.model('Users');
router.post('/createuser', auth.required, (req, res, next) => {
const { payload: { id } } = req;
//var id = req.get("authorization");
console.log("in create User route");
return Users.findById(id)
.then((user) => {
if(!user) {
return res.sendStatus(400);
}
//res.send(req.body);
res.redirect(307,'http://localhost:8181/user');
});
});
I hit the URL from Advance Rest Client and get this statement
"Temporary Redirect. Redirecting to http://localhost:8181/user"
but there is no redirection. i also tried
res.redirect(302,'http://localhost:8181/user');
and
res.redirect('http://localhost:8181/user');
but it doesn't work.
I did not tried this using express. But below code works in node.
res.writeHead(302,{'Location':'url/test'});
res.end();
Just do res.redirect('/myroutes'); You don't need to declare your host as well.
Related
Im learning to use JWT. I setup a very simple react app and an express server that uses a json file as database to try it but when i return a cookie via res.cookie the request is stuck on pending according to my browsers network tab.
This is how my server looks
const express = require("express");
const cors = require("cors");
const cookieParser = require("cookie-parser");
const jwt = require("jsonwebtoken");
const { JsonDB, Config } = require("node-json-db");
require("dotenv").config();
const server = express();
server.use(express.json());
server.use(cors());
server.use(cookieParser());
const db = new JsonDB(new Config("db", true, false));
server.post("/login", async (req, res) => {
const { username, password } = req.body;
const data = await db.getData("/users");
const user = data.find((user) => {
return user.username === username && user.password === password;
});
if (!user) {
return res.status(403).json({
error: "invalid login",
});
}
const token = jwt.sign(user, process.env.MY_SECRET, { expiresIn: "1h" });
return res.cookie("token", token, { httpOnly: true });
});
server.get("/logout", (req, res) => {
console.log("cleared token");
return res.clearCookie("token");
});
server.listen(3000, () => {
console.log("server listening on port 3000");
});
And this is my request in my react app
const handleSubmit = async () => {
const username = usernameRef.current.value;
const password = passwordRef.current.value;
const response = await axios.post("http://localhost:3000/login", {
username: username,
password: password,
});
console.log(response);
};
I've tried changing the order of the middlewares around and adding next() at the end but didn't work. Sending data via res.send works just fine. I've worked with express about a year ago but never ran into this.
res.cookie only set cookie. It doesn't response to client. After res.cookie, use res.send, res.json or any method to response.
I create user service with login and register in node js. when i using authenticate middleware i got this kind of errors. if any one have solution. please let me know. i attached code and error image.
this is my route file.
const { Router} = require('express');
const authController = require('../controllers/authController');
const {authMiddleware} = require('../middleware/authMiddleware')
const router = Router();
router.get('/users',{authMiddleware}, authController.users_get);
router.post('/users',authController.users_post);
router.post('/authenticate',authController.authenticate_post);
module.exports = router;
this is my middleware file
const jwt = require('jsonwebtoken');
const requireAuth =(req, res, next)=>{
const token = req.cookie.jwt;
//check json web token exists & is verified
if(token){
jwt.verify(token,'vivekeviv',(err, decodedToken)=>{
if (err){
console.log(err)
}
else {
console.log(decodedToken);
next();
}
})
}
else {
console.log("You need to login")
}
}
module.exports ={requireAuth}
how to add middleware to this code.
i got this kind of error.
You are passing an object where express is expecting a function. You want:
const {requireAuth} = require('../middleware/authMiddleware')
...
router.get('/users', requireAuth, authController.users_get);
I have a route of type post, that is receiving some info from the front-end, as shown below:
const router = require("express").Router();
const UsernameController = require("../controllers/username.controller");
router.post("/username", async (req, res) => {
try {
const cookie = req.cookies;
const {userName} = req.body;
let allGames = await new UsernameController().getGames(userName);
console.log(allGames[0].games)
return res.sendStatus(200)
} catch (err) {
console.log(err);
res.status(422).send(err);
};
});
module.exports = router;
I need to use the destructured {userName} = req.body in another file. So I’m wondering how I can export the {userName} received from the front-end to the middleware.js file.
middleware.js:
const AuthController = require("../controllers/auth.controller");
const UsernameController = require("../controllers/username.controller");
const usernameRouter = require('../routes/username.route')
module.exports = async (req, res, next) => {
let userName = usernameRouter.userName
const userGamesArray = await new UsernameController().getGames(userName)
req.userGamesArray = userGamesArray;
next();
};
When I console.log the userName variable in the middleware file, it responds with undefined which means I’m importing the variable wrongly from the route.js file.
Kindly assist me with importing the variable from the route.js file to the middleware.js file.
You just need to use a middleware in this /username route like this:
const middleware = require("./middleware"); // correct this path to a real one
router.post("/username", middleware, async (req, res) => {
...
I have making an API using express and node.
Here is my app.js
const express = require('express');
const bodyParser = require('body-parser');
const dotenv = require('dotenv');
// setup dotenv to read environment variables
dotenv.config()
// Load Environment Varibles
const env = require('./utils/env');
// INIT MONGODB CONNECTION
require('./mongoose');
// create a new express application
const app = express();
// setup bodyparser middleware to read request body in requests
// we're only reading JSON inputs
app.use(bodyParser.json());
// Listen to API routes
const apiRoutes = require('./routes')
app.use('/api', apiRoutes);
// Start listening to requests
app.listen(env.PORT, () => {
console.log(`Server started on PORT ${env.PORT}`);
});
And here is the API routes that are being imported
const express = require('express');
const apiController = require('./apiController');
const apiValidator = require('./apiValidator');
const router = express.Router();
router.post('/login', apiValidator.loginUserValidator, apiController.loginUserController);
router.get('/rand', (req, res) => {
res.send('Some randon text');
});
module.exports = router;
Here is the middleware
const {
failureResponse
} = require('./../utils/response');
const errorcodes = require('./../utils/errorcodes');
const loginUserValidator = (req, res, next) => {
const user = req.body;
if (!user.username) {
return res.status(400).json(failureResponse(errorcodes.ERROR_INVALID_BODY_PARAMETER, "Invalid username"));
}
if (!user.password) {
return res.status(400).json(failureResponse(errorcodes.ERROR_INVALID_BODY_PARAMETER, "Invalid password"));
}
if (user.authTokens) {
delete user.authTokens;
}
next();
};
module.exports = {
loginUserValidator
};
Here is the controller
const User = require('./../models/user');
const {
successResponse,
failureResponse
} = require('./../utils/response');
const errorcodes = require('./../utils/errorcodes');
const loginUserController = async (req, res) => {
try {
const user = req.body;
// find if the user already exists
const existingUser = await User.findOne({
username: user.username
});
if (existingUser) {
// user exists. generate token and login user
console.log('Existing user login');
const token = existingUser.generateAuthToken();
return res.status(200).json(successResponse(token));
} else {
console.log('New user login');
const savedUser = await new User(user).save();
const token = savedUser.generateAuthToken();
return res.status(200).json(successResponse(token));
}
} catch (e) {
console.log(e);
return res.status(400).json(failureResponse(errorcodes.ERROR_SERVER_ERROR, "Unable to login user"));
}
};
module.exports = {
loginUserController
};
Here the issue is when I try to hit the login route from Postman, I am getting an error which says Could not get any response.
But when I hit the rand route, the output is correct.
So the issue isn't the arrangement of the code.
Why am I not able to use the login route here?
For example, in Meteor, there's something like
Router.plugin('ensureSignedIn');
Router.plugin('ensureSignedIn', {
except: ['home', 'atSignIn', 'atSignUp', 'atForgotPassword']
});
So unsigned user cannot access other routes except above four.
How to do this in express.js? I'm using passport.js also.
I'm not familiar with Meteor, but you can do something like the following, assuming you want to make pages available to only authenticated users (passport).
function ensureAuthenticated(req, res, next) {
if (req.isAuthenticated())
return next();
else
// Return error content: res.jsonp(...) or redirect: res.redirect('/login')
}
app.get('/account', ensureAuthenticated, function(req, res) {
// Do something with user via req.user
});
The ensureAuthenticated function is just an example, you can define your own function. Calling next() continues the request chain.
I should use middleware for protect my routes, even to protect certain verbs in the same route:
for example: in my endpoint/route.js
// the require sentences are omitted
const express = require('express');
const { /*controllerFunctions*/ } = require('./controller');
const {routeGuard} = require('/*must create a route guard*/');
const router = express.Router();
router.route('')
.get(getAllResources)
;
router.route('/:id') //
.get(validateParam,getOneResource);
router.use(routeGuard);
router.route('/:id')
.post(validateParam,validateBody,postResource)
.patch(validateParam,validateBody,patchProblemById)
.delete(validateParam,deleteResource)
;
module.exports = router;
and my routeGuard file should be like this:
const { promisify } = require('util');
const jwt = require("jsonwebtoken");
const AppError = require('./appError');
const {User} = require('./../endpoints/users/model');
const wrapper = require('./try-wrapper');//try catch wrapper
module.exports.routeGuard = wrapper(async function (req, res, next){
// the err message is the same on purpose
const notAllowed = new AppError('Unauthorized: Invalid or Nonexistent credentials',401);
let token = null;
if (req.headers.authorization && req.headers.authorization.startsWith('Bearer')){
token = req.headers.authorization.split(' ')[1];
}
if (!token) return next(notAllowed );
const payload = await promisify(jwt.verify)(token,process.env.KEY);
const user = await User.findById(payload.id);
if (!user) return next( notAllowed);
if ( ! user.hasSamePasswordSince(payload.iat) )return next( notAllowed );
req.user = user; // further use...
next();
});