I'm using express 4.9.0.
I have the following code in my user.js file inside route folder.
/* Get User by id. */
router.get('/:id', function(req, res) {
console.log('find user ' + req.params.id);
User.findById(req.params.id, function (err, user) {
if (!err) {
return res.send(user);
}
return console.log(err);
});
});
Later, in app.js:
app.use('/users', users);
However, when i navigate to http://localhost:3000/users?id=546e5640f5fea84a345abe2c the route is never hit. Calls to other routes work fine.
What am I doing wrong?
For the route you currently have, you'd need to make your request url this: /users/546e5640f5fea84a345abe2c.
If you want your route to match the request url you're currently trying (/users?id=546e5640f5fea84a345abe2c), then you would instead do:
/* Get User by id. */
router.get('/', function(req, res) {
console.log('find user ' + req.query.id);
User.findById(req.query.id, function (err, user) {
if (!err) {
return res.send(user);
}
return console.log(err);
});
});
Related
My app is on express, mongoDB. I add authorization by session. Don't work logout. There is the link on a page (this is pug):
a(href="/logout") logout
It's handler:
app.get('/logout', function (req, res, next) {
if (req.session) {
// delete session object
req.session.destroy(function (err) {
if (err) {
return next(err);
} else {
return res.redirect('/');
}
});
}
});
When clicked, it displays this and redirect does not occur. If you delete everything except redirect, then redirect will work. But I need to delete the authorization session.
try something like this
app.get('/logout', function (req, res, next) {
// If the user is loggedin
if (req.session.loggedin) {
req.session.loggedin = false;
res.redirect('/');
}else{
// Not logged in
res.redirect('/');
}
});
If you are using passportjs, you need to call the req.logout() to terminate a login session. See documentation here
Background:
I'm writing my first MEAN application. I'm trying to create an API that allows basic CRUD ops on a collection called "chassis".
Problem
So far, i can GET all records using find(). I can also findById, and update existing records, no problems.
However, when I try to POST, I get the following error:
dev#devbox:~/nimble_express/nimbleApp$ curl -X POST localhost:3000/chassis/ -d name=widget123 -d location=Canada -d ffd=test123 -d hw_model=hp -d asset_tag=12344
<h1>document must have an _id before saving</h1>
<h2></h2>
<pre>Error: document must have an _id before saving
at null._onTimeout (/home/dev/nimble_express/node_modules/mongoose/lib/model.js:112:18)
at Timer.listOnTimeout [as ontimeout] (timers.js:110:15)</pre>
dev#devbox:~/nimble_express/nimbleApp$
Code
I have the following logic in a routes/chassis.js file:
var express = require('express');
var router = express.Router();
//var mongoose = require('mongoose');
var Chassis = require('../models/Chassis.js');
/* GET chassis listing. */
router.get('/', function(req, res, next) {
Chassis.find( function(err, documents) {
if (err) return next(err);
res.json(documents);
});
});
/* GET /chassis/id */
router.get('/:id', function(req, res, next) {
Chassis.findById(req.params.id, function (err, post) {
if (err) return next(err);
res.json(post);
});
});
/* POST /chassis */
router.post('/',function(req, res, next) {
console.log(req);
Chassis.create(req.body, function(err, post) {
if (err) return next(err);
res.json(post);
});
});
/* UPDATE /chassis/id */
router.put('/:id', function(req, res, next) {
Chassis.findByIdAndUpdate(req.params.id, req.body, function(err, post) {
if (err) return next(err);
res.json(post);
});
});
module.exports = router;
~
I've tried googling for this error but haven't found anything too useful yet.
Any pointers would be helpful and appreciated!
I am trying to write a code for user login authentication in express using express-session
This is my accounts.js api
.use(bodyParser.urlencoded())
.use(bodyParser.json())
.use(session({ secret: 'hcdjnxcds6cebs73ebd7e3bdb7db73e' }))
.get('/login', function (req, res) {
res.sendfile('public/login.html');
})
.post('/login', function (req, res) {
var user = {
username : req.body.username,
password : hash(req.body.password)
};
var collection = db.get('users');
collection.findOne (user, function (err, data) {
if (data) {
req.session.userId = data._id;
res.redirect('/');
} else {
res.redirect('/login');
}
});
})
.get('/logout', function (req, res) {
req.session.userId = null;
res.redirect('/');
})
.use(function (req, res, next) {
if (req.session.userId) {
var collection = db.get('users');
collection.findOne({ _id : new ObjectId(req.session.userId)}, function (err, data) {
req.user = data;
});
}
next();
});
module.exports = router;
And this is my server.js code
var express = require('express'),
api = require('./api'),
users = require('./accounts'),
app = express();
app
.use(express.static('./public'))
.use('/api', api)
.use(users)
.get('*', function (req, res) {
if (!req.user) {
res.redirect('/login');
} else {
res.sendfile(__dirname + '/public/main.html');
}
})
.listen(3000);
My problem is, in server.js, req.user is getting null value that's why i am not able to login. But in account.js req.user getting user data which is not reflecting in server.js.
Again, if in accounts.js, I am placing next() inside the if (req.session.userId) statement, I am able to get user data in server.js but it creating problem in logout.
Please help me out in this.
Your accounts.js is executing next() before your collection query returns, so it makes sense that your req.user is undefined in your middleware later on. To fix it, try this:
.use(function (req, res, next) {
if (req.session.userId) {
var collection = db.get('users');
collection.findOne({ _id : new ObjectId(req.session.userId)}, function (err, data) {
req.user = data;
next();
});
} else {
next();
}
});
As a side note, you're very much reinventing the wheel here by implementing user login yourself. I would reccommend taking take a look at passportjs for doing user login like this.
Currently using node.js, express & passport.js to create a custom website/application.
Having followed several guides, I have a functioning login/logout system with authentication. However, should a user revisit and their session is still active, it doesn't redirect them to the 'dashboard'.
Current root route:
/* GET login page. */
router.get('/',function(req, res) {
// Display the Login page with any flash message, if any
res.render('index', { message: req.flash('message') });
});
I am making use of the isAuthenticated function, as below:
var isAuthenticated = function (req, res, next) {
if (req.isAuthenticated())
return next();
res.redirect('/');
}
How do I get it to automatically redirect users with an existing session? Any pointers most welcome!
Ok, I figured it out. In the / route, I queried whether req.user was set.
/* GET login page. */
router.get('/',function(req, res) {
if(req.user){
res.redirect("/dashboard");
}else{
// Display the Login page with any flash message, if any
res.render('index', { message: req.flash('message') });
}
});
You can attach a middleware with "/" endpoint something like this.
router.get('/', sessionValidate, function(req, res, next) {
res.render('login');
});
Where sessionValidate looks something like this :
function sessionValidate(req,res,next){
console.log(req.user,"i am here");
users.findById(req.user,function(err, user) {
if(user!=null){
req.session.user = user;
res.locals.user=user;
res.redirect("/home")
}
else {
next();
}
});
}
This is similar to this question, but my code has multiple routes.
The code works below for what I want to do, but I want to know if there's a cleaner way to write it as I'm fairly new to Node/Express/Redis.
var express = require('express');
var router = express.Router();
var io = require('socket.io');
var redis = require('./../lib/redis');
redis.get('count', function(err, value) {
if(err) throw err;
/* GET Dashboard */
router.get('/', function(req, res) {
res.render('dashboard', {title: 'Data Dashboard', count: value });
});
/* GET Backend */
router.get('/backend', function(req, res) {
res.render('backend', {title: 'Backend', count: value });
});
});
module.exports = router;
Basically, I'm just passing a single Redis key-value to both of my routes.
Any suggestions to clean it up are appreciated.
The way your code is written you'll be passing the same value of the count key for your whole application life-cycle. There's nothing wrong with the code from a cleaning up perspective, but from a service point of view, the routes shouldn't be within the REDIS GET callback.
Getting the value within the route
// Use everytime you need to count the key
function redisCount = function(callback) {
redis.get('count', function(err, value) {
if(err) callback(err)
callback(null, value)
}
}
/* GET Dashboard */
router.get('/', function(req, res) {
redisCount(function(err,value) {
if(err) throw err;
res.render('dashboard', {title: 'Data Dashboard', count: value });
})
});
/* GET Backend */
router.get('/backend', function(req, res) {
redisCount(function(err,value) {
if(err) throw err;
res.render('backend', {title: 'Backend', count: value });
})
});
However if you do this count call for absolutely every single route, I would suggest a piece of middleware that just sets value into the context for every call:
Getting the value in a separate middleware
app.use(function (req, res, next) {
// using the same function for the redis count
redisCount(function(err, value) {
// respond with error
if (err) res.status("Could not connect to Redis")
// otherwise set the value in the session
req.session.value = value
// and move on to the next middleware
next()
});
});
// now simply declare your routes
/* GET Dashboard */
router.get('/', function(req, res) {
res.render('dashboard', {title: 'Data Dashboard', count: req.session.value });
});
/* GET Backend */
router.get('/backend', function(req, res) {
res.render('backend', {title: 'Backend', count: req.session.value });
});