0

How can I write my simple user-login system in the Node way, with callbacks?

I'm attempting to write a simple login validation script with node, but node's asynchronous callback methodology just hasn't clicked for me. I'll show my scarily bad simple login system script so you can see how lost I am with this concept. I'm just trying to grasp the concept of doing this asynchronously.

Resources:

I'm using express and node-mysql.

I set up an index and 4 simple modules: login, server, validator, and db_connect. Here's the app source:

https://gist.github.com/anonymous/9313703

Here is my login module, where my issue becomes obvious:

console.log('login module initialized');

var express     = require('express');
var app         = express();
var validator   = require('./validator');

var username;
var password;

function loginSucceed(){
    res.writeHead(302, {'Location': 'http://localhost/officeball/app.php'});
    console.log('user ' + req.body.email + ' logged in successfully.');
    res.end();
}

function loginFail(){
    res.writeHead(302, {'Location': 'http://localhost/officeball'});
    console.log('user ' + req.body.email + ' failed to validate.');
    res.end();
}

function listen(){
    app.use(express.bodyParser());

    app.post('/login', function(req, res) {
        console.log('User ' + req.body.email + ' is attempting login...');
        username = req.body.email;
        password = req.body.password;
        validator.validate(username,password,callback); 
    });

    app.listen(8080, function() {
        console.log('Server running at http://127.0.0.1:8080/');
    });
}

exports.listen = listen;

In listen(), I need validate() to execute either loginFail() or loginSucceed() depending on the validation with the database, but I don't think I even went about that the right way.

2 Answers2

0

probably you need to use the already created solution - http://passportjs.org/

vodolaz095
  • 6,242
  • 4
  • 24
  • 41
  • FWIW, I would suggest that until a person gets their head around how to use a toolset, throwing libraries at a problem is not helpful in all but the most immediate case - it's the reason you see people (e.g.) loading jQuery for a single function that is really just one line of javascript they should have taken the time to reason through. The login use case, in its barest form, is simple enough it's a good learning tool. – barry-johnson Mar 02 '14 at 21:17
  • i mean "use" = get the code and find out how does it work. I think the current code of topic starter have some major flaws - no session persistance and validation of data entered, so probably it is better to learn how it is done in solution used in 80% of production ready applications. So, i send the link to passportjs framework – vodolaz095 Mar 02 '14 at 21:23
  • I'd agree with that 100%. My closing line in my original answer to the OP suggested checking out some node github projects. – barry-johnson Mar 02 '14 at 21:26
  • I'll look at that source code if you think it'll help. The code of advanced JS programmers often confuses me with the clever syntax usage and shortcuts that they use. It's like trying to read French poetry after just a month of learning French. –  Mar 02 '14 at 21:57
0

A gentle suggestion: you need to slow down and read the answers you are getting more comprehensively and also do a little more research.

Look at the code I provided, in my first answer to you about this question, which you copied, pasted, and then altered in a breaking way.

            if (rows[0].password === password) {
                // you would probably want a more useful callback result than 
                // just returning the username, but again - an example
                return callback(null, rows[0].username);
            } else {
                return callback(new Error ('Bad Password'), null);
            }

You changed this to:

            if (rows[0].password === password) {
                loginSucceed();
            } else {
                loginFail();
            }

I am not sure what motivated you to take the callbacks out of the code.

Using the code I posted, you would change the code back to what I gave you originally and then change your line in the code you posted in this question from:

validator.validate(username,password,callback);

to:

validator.validate(username,password,function(err,result){
    if (err) loginFail();
    else loginSucceed();
});

UPDATE To illustrate the access to res/req via closures.

Since the only place you are really using loginFail() and loginSucceed you could rewrite what you have this way. In this case, you don't need to worry about passing req and res to the functions because they are available via closure. I inlined the username/pass parametere for brevity

function myLoginHandler (req, res) {
    // define your functions within the myLoginHandler scope

    function loginSucceed(){
        res.writeHead(302, {'Location': 'http://localhost/officeball/app.php'});
        res.end();
    }
    function loginFail(){
        res.writeHead(302, {'Location': 'http://localhost/officeball'});
        res.end();
    }
    // and call them the same you did
    validator.validate(req.body.email, req.body.password ,function(err,result){
        if (err) loginFail();
        else loginSucceed();
    });
}
// then you just register your function as the /login handler.
function listen(){
    app.use(express.bodyParser());
    app.post('/login', myLoginHandler);
    app.listen(8080, function() {
        console.log('Server running at http://127.0.0.1:8080/');
    });
}
Community
  • 1
  • 1
barry-johnson
  • 3,173
  • 1
  • 15
  • 19
  • Right, when I attempted to combine the validation script that you provided in the first question, I muddled it up not seeing the proper way to use the callbacks. I will slow down, but I find that learning a new code concept always happens quickly once I ask a question from a few different angles. Thank you. A primary issue here is lack of experience with javascript. I've read the documentation. Just grasping the concept of the callback rather than the proceedural return. –  Mar 02 '14 at 21:35
  • You're welcome. While it is not node-specific at all, I strongly recommend Douglas Crockford's 'Javascript: the Good Parts' as well as some of the lectures you can find from him on Youtube (he did a good series of them for a YUI conference as I recall). The three other general things you'll need to get your head around with Javascript are probably a) it is a functional language (i.e. functions are first class objects) and b) closures (which relate to the accessibility of variables within scopes) and c) JS's prototypal (vs **class** ical) approach to inheritance. – barry-johnson Mar 02 '14 at 21:42
  • Looking at you experienced programmers write it out like poetry is something.. I'm working towards it. I'll take a look at that, also reading this book. http://www.nodebeginner.org/ - it'll probably make more sense as I get further in. –  Mar 02 '14 at 21:49
  • Oh, question: how can I pass the `res` object to my success/fail functions? Can I just pass it in as a parameter? Getting a reference error as it is. –  Mar 02 '14 at 21:51
  • got it, passed in `res,req` into the functions –  Mar 02 '14 at 22:07
  • 1
    OK. That is one way to do it. I will edit the answer to illustrate an alternative way as well. – barry-johnson Mar 02 '14 at 22:08
  • From skimming over the nodebeginners thing, I question how helpful it will really be to you. It reads like he has hacked his way through developing a node app. I see hardly any mention of "why" he does anything or "how" what he does works; the absence of either doesn't offer much learning opportunity, IMHO. "Learn by snippet" only gets one so far. – barry-johnson Mar 02 '14 at 22:35
  • Is there a better node beginner book/tutorial set that you would recommend? –  Mar 03 '14 at 21:23
  • let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/48906/discussion-between-barry-johnson-and-jt0dd) – barry-johnson Mar 03 '14 at 21:33