0

I am using node and trying to redirect a client after he authorizes himself. For this reason I am using a POST method using ajax on the client side which has the form:

$.ajax({
    type: "POST",
    url: '/login',
    dataType: "json",
    async: false,
    beforeSend: function(xhr) {
        xhr.setRequestHeader("Authorization", "Basic " + btoa(credentials.username + ":" + credentials.password));
    },
    data: credentials,
    success: function () {
        window.alert("Success! (whatever that means)");
    }
});

Then on the server side I am trying to redirect to the actual page with the commands

app.get('/login', loginInternalApp);
app.post('/login', function (req, res){
    var postContents = req.body;
    req.session.username = postContents.username;
    res.redirect('/my_secret_page');
});
app.get('/my_secret_page', checkAuth, function (req, res) {
    console.log("sending the message!");
    res.send('if you are viewing this page it means you are logged in');
    res.end();
});

where checkAuth was taken from here how to implement login auth in node.js (instead of user_id I am using username; that's not the problem).

Perhaps what I do not know is how to treat this ajax call correctly. I print some console messages and the server goes all the way to the res.send('if you are viewing this page...') however, nothing happens on the client. Then when I press a control-C to terminate the server, the alert window pops up. Meanwhile, I can see that the function passed on success can have parameters (guessing now: errorCode, errorString, otherData, perhaps more).

So what am I doing wrong?

Community
  • 1
  • 1
MightyMouse
  • 13,208
  • 8
  • 33
  • 43

1 Answers1

3

The issue here is that you are a little confused between the concepts of JavaScript-powered navigation and straight up server request-response powered nav. Let's go through this for a minute and see if it makes more sense.

You are using ajax to submit your login form, which means you stay on the page that you are on, and just submit your http request with JavaScript, collecting the response. You put up the POST, and your server logs the user in, then returns a 3XX indicating a redirect. Your JavaScript collects the response, which you can see if you open up your inspector under the "network" tab. But the page doesn't go anywhere because you are just collecting your response with JavaScript.

In this case, you want to choose one or the other -- use JavaScript to handle your routing (tools like backbone are super useful in cases like these and come with nice routing classes), or submit the login form normally, not through ajax. If you let the form submit when the user hits the button and do not catch it with JS, this should fix the problem - if you return a redirect from the server, the page will redirect as expected. Alternately, if rather than sending a redirect response, you could send back JSON indicating success or failure, then use JavaScript to display the appropriate view, and this would also solve the issue.

Looking at your server-side code, I assume the reason you are using ajax here is in order to set the authorization headers. I'm not sure why you need those, as you hid the internal auth function, but you might see an issue with not using ajax being that you would not have those custom set headers by default in a normal form submission. There are certainly ways to collect the same information and move it in the same ways (you can set headers, delegate to other methods, and even send off http requests from express), but I'd need more details on how specifically you are handling logins to advise on how to streamline that piece : )

BenMorel
  • 34,448
  • 50
  • 182
  • 322
Jeff Escalante
  • 3,137
  • 1
  • 21
  • 30
  • If I submit the login normally by making the button a 'submit' button, then it actually performs a GET to the address: GET /login?username=whatever&password=something which is clearly not what I want. All I really want is to submit with a POST (should I use PUT?) the user credentials, set up the username in the session, and in subsequent calls from the client side to use the username found in the session in order to figure out who is GETting/PUTting/POSTing/etc. I am using ajax because it is simple. I gather the data and I want to issue a POST. – MightyMouse Oct 24 '13 at 15:31
  • I changed the headers because I found somewhere in SO that this has to happen in order for things to work. Honestly, I want to do something as simple as that. – MightyMouse Oct 24 '13 at 15:32
  • Voted up because it helps. – MightyMouse Oct 24 '13 at 15:38
  • 1
    Ah, you just have to change the [form `method`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/form) to `POST`, as such `
    `. As far as changing the headers like this, you don't need it then if you just put that in for kicks.
    – Jeff Escalante Oct 24 '13 at 15:42
  • Thanks. That thing worked when I also removed my statements res.end() that I had. However, this is not really solving my issues, because I think the method PUT, which will be necessary for other operations, can not be used when submitting the form. So, I really have to do this with ajax. Any idea on this one? – MightyMouse Oct 24 '13 at 15:53
  • 1
    You can use `PUT` if you want, just specify it as the form method : ) – Jeff Escalante Oct 24 '13 at 15:54
  • I will trust you on that one and I am accepting. Thanks for your time. – MightyMouse Oct 24 '13 at 16:02