I create a rout that get user full details from the DATABASE(mongoDB).
Router
router.get('/user/:userid/:name', getUrl, function(req, res, next) {
User.findOne({_id: req.params.userid})
.exec(function(err, user) {
if (err) { return next(err); }
if (!user) { return next(404); }
res.render('........');
});
});
for instance i can access this router with this URL:
http://127.0.0.1/user/6465667/username
but what i realy want is this
http://127.0.0.1/user/username
Is there a way of hiding the user ID in the URL
Simply remove :userid from your route and use the name to lookup your database. Ensure your username is unique otherwise you might receive the wrong user details.
router.get('/user/:name', getUrl, function(req, res, next) {
User.findOne({name: req.params.name})
.exec(function(err, user) {
if (err) { return next(err); }
if (!user) { return next(404); }
res.render('........');
});
});
Related
I'm using PassportJS. I'm trying to let users edit their email address if needed. This is the code I have which is currently not working.
Any advice? Thank you!
app.post("/editprofile", middleware.isLoggedIn, function(req, res, next){
User.update({ id: req.session.passport.user }, {
email: req.body.email,
}, function(err, user) {
if (err) return next(err);
User.findById(req.user._id, function(err, user) {
if (err) return next(err);
console.log(err)
return res.render('landing.ejs', {
user:user
});
});
});
});
Consider using this and every thing will be fine
app.post("/editprofile", middleware.isLoggedIn, function(req, res, next){
User
.findOneAndUpdate({ _id: request.session.passport.user }, req.body.email)
.exec(function(err, user) {
if (err) return res.render(/* Your error template here */, {
err: err.message
};
return res.render('landing.ejs', {
user: user
});
});
}
}
Hope this helps!
Here is the code:
exports.delete = function (req, res, next) {
console.log(req.user);
req.user.remove(function (err) {
if(err) {
return next(err);
} else {
res.json(req.user);
}
})
};
Of course this function is callback of delete method, what I don't understand is that, why removing req.user also deletes the specific user from MongoDB, as it is just a request.
Edit:
I have another callback(GET) which is executed on the same route:
exports.userByID = function (req, res, next, id) {
User.findOne({
_id: id
}, function (err, user) {
if (err) {
return next(err);
} else {
req.user = user;
next();
}
});
};
User is MongoDB model.
Where you do your req.user = user you're setting the value of req.user to the instance of your mongodb model.
So, calling req.user.remove is in fact calling your mongodb model remove function.
Change your delete function to:
exports.delete = function (req, res, next) {
console.log(req.user);
delete req.user
//etc...
};
delete req.user will remove the user object from your request object
I am using nodejs for a project,now I want login my account with passport npm,but not from webpage,from request post method,can it be done?
main code like this:
router.post('/login',function(req, res, next) {
passport.authenticate('local', function(err, user, info) {
if (err) { return next(err); }
if (!user) { return res.json(null); }
req.logIn(user, function(err) {
if (err) { return next(err); }
//return res.redirect('/'); redirect not work
});
})(req, res, next);
});
router.get('/check',function(req, res, next) {
request.post({
url:'http://localhost/login',
headers:{
'Content-Type': 'application/x-www-form-urlencoded'
},
form:{
username:'myname',
password:'mypassword'
}},function(err,httpRes,body){
//do here...?
return res.redirect('/');
});
});
When I call "check" with get method and use the correct username/password,I can print out the user data from database in "login" method,but lost the user session when it redirect home page.Any suggestion?
It's not redirecting the user when they GET /check because the POST request to /login in /check is getting redirected itself, not the actual user. Also making internal requests to internal webpages isn't the best solution for logging in. I suggest creating login() middleware like so:
// Don't forget to set req.body.username and req.body.password when calling login().
var login = function login(req, res, next) {
passport.authenticate('local', function(err, user, info) {
if (err) { return next(err); }
if (!user) { return next(); }
req.logIn(user, function(err) {
if (err) { return next(err); }
return next(null);
});
})(req, res, next);
};
And then calling it appropriately:
router.post('/login', login, function(req, res, next) {
if (req.user) {
console.log('We logged in successfully!');
res.redirect('/');
} else {
res.json(null);
}
});
router.get('/check', function(req, res, next) {
if (!req.user) {
login(req, res, function(err) {
if (err) {
return next(err);
}
if (!req.user) {
// No user, do some error handling.
} else {
// We have the user, do some custom stuff...
}
res.redirect('/');
});
} else {
// User is logged in already, do some other custom stuff...
}
});
You can check if a user is logged in by checking if req.user exists.
I'm authenticating my nodeJs app using passport local strategy. Everything is working fine. But how can I show the user appropriate message that he has entered invalid login credentials. My present code is just sending 401 unauthorized error on screen.
Here is my code
passport.use(new LocalStrategy(function(username, password, callback) {
User.findOne({
username : username
}, function(err, user) {
if (err) {
return callback(err);
}
// No user found with that username
if (!user) {
return callback(null, false);
}
// Make sure the password is correct
user.verifyPassword(password, function(err, isMatch) {
if (err) {
return callback(err);
}
// Password did not match
if (!isMatch) {
return callback(null, false);
}
// Success
return callback(null, user);
});
});
}));
exports.isLocalAuthenticated = passport.authenticate('local', {
session : true
});
router.post('/', authController.isLocalAuthenticated, function(req, res) {
//here I want to show the error message to user
});
The documentation has clearly described your case under Custom Callback section.
You need to add custom callback like this:
exports.isLocalAuthenticated = function(req, res, next) {
passport.authenticate('local', function(err, user, info) {
if (err) { return next(err); } //error exception
// user will be set to false, if not authenticated
if (!user) {
res.status(401).json(info); //info contains the error message
} else {
// if user authenticated maintain the session
req.logIn(user, function() {
// do whatever here on successful login
})
}
})(req, res, next);
}
You don't need to specify the latter callback.
On a successful signup of a user I am currently seeing a mostly empty page with the text undefined. Redirecting to /app at the top.
UPDATE: I should also mention that after form submittal I am redirected to /users. So on /users I see the text mentioned above.
I think it is because of the req.redirect call being within the user.save callback but I am not sure what the fix is.
I am using mongoose for the ORM.
var User = require('../models/user');
module.exports = function(app) {
app.post('/users', function(req, res, next) {
var user = new User({
email: req.body.email,
password: req.body.password
});
user.save(function(err) {
if (err)
res.send(412, {message: err});
else
req.login(user, function(err) {
if (err !== undefined) return next(err);
res.redirect('/app', {
email: user.email,
id: user._id
});
});
});
});
};
It turns out that the req.login call has to be contained in a password.authenticate callback. The example on the site left that part out.
user.save(function(err) {
if (err)
res.send(412, {message: err});
else
passport.authenticate('local', function(err, user) {
if (err) { return next(err) }
if (!user) { return res.redirect('/login') }
req.login(user, function(err) {
if (err) { return next(err); }
return res.redirect('/app', { email:user.email, id:user._id });
});
})(req, res, next);
});