I'm working on an app which has node.js and express on the server, mongodb for the db and Backbone.js on the front-end. I'm working on enabling user logins, so I've used the passport.js library. I have a problem with my login 'post' method: It is not redirecting to another page (well it's an SPA, so I mean rendering a Backbone view). Here's the code:
//standard express setup...
app.post('/api/auth', function(req, res, next) {
passport.authenticate('local', function(err, user, info) {
if (err) { return next(err) }
if (!user) {
req.session.messages = [info.message];
return res.redirect('/')
}
req.logIn(user, function(err) {
if (err) {
return next(err);
} else {
console.log('yup, working'); //Can see the response in the console
return res.redirect('/api');
}
});
})(req, res, next);
});
app.get('/api', function (request, response) {
response.send( 'Login successful!' );
});
So I can see the console.log message fine, and a GET request for the route IS triggered...but nothing actually happens. So I'm thinking that I've misunderstood how 'res.redirect' works - I want to navigate to that route upon the login success. I've thought about using window.location, but is this a good long-term solution? I'm not using any html templates on the server, so I can't (I don't think) do something as simple as 'res.render('index')'
What would be the best way to approach this? Thanks in advance.
I had a face-palm moment a few days after asking this question where I realized I had failed to grasp a core concept correctly. Let me answer my own question:
Rather than trying to serve the page from the server, I just need to send a response to the client and have Backbone do the rendering, depending on the response received. So my server does something more like this:
controller.post('/user', function(req, res, next) {
passport.authenticate('local', function(err, user, info) {
if (err) { return next(err) }
user.save(function(err) {
if(err){
console.log(err);
return res.json(401);
} else {
return res.json(200); //SEND RESPONSE - do not try to redirect
}
});
Then I do the page loading in the Backbone View, like this:
login: function (e) {
e.preventDefault();
console.log('submitting login request');
var formValues = {
username: $('#inputEmail').val(),
password: $('#inputPassword').val()
};
var user = new User(); //user model
user.set(formValues);
function saveUserfunction (){
if(user) {
user.save(this.formValues, {
success: function(model, response, options) {
if (response == 200) {
console.log('success :' + response);
window.location.href = 'http://localhost:4711/#/api/menu_auth'; //Here's my redirect - the router is listening for this route and will render accordingly
} else {
console.log('error: '+response);
}
}, error: //Error handling etc.
As Pheonix pointed out in the comments, the best way to do this would be to listen to the the user model.