Node.js username and password authentication

Problem

I'm currently building a web app using Node.js and Express.js.

I'm looking for a way to have a simple server-side authentication with a username and password in my main app.js file which is listening for a post request at http://www.domain.com/login:

app.js

app.post('/login', function(req, res) {
  // some server-side code for a username and password
}

On the client-side I have a simple login form with a username and password. This form is going to posted to the server:

index.html

<form method="post" action="/login">
<input type="text" id="user" name="user" />
<input type="password" id="pass" name="pass" />
<button type="submit">Login</button>
</form>

I am looking to achieve this without the use of any ExpressJS plugins.

Edit: So my question is, how do I achieve a simple username and password authentication in ExpressJS and NodeJS?

Problem courtesy of: Jasdeep Khalsa

Solution

I found the answer I was looking for using the Connect middleware included with ExpressJS, without the need to use cookies or add in another Node module:

var express = require('express');

function authorize(username, password) {
    return 'someone' === username & 'password' === password;
}

var app = express.createServer(
    express.basicAuth(authorize)
);

app.get('/', function(request, response) {
    response.send('Authorized!');
});

console.log('Starting server...')
app.listen(8080);

After running the application and navigating to http://localhost:8080, it prompts for a username and password. Simples.

Solution courtesy of: Jasdeep Khalsa

Discussion

With the use of ExpressJS sessions, you may hold session cookies. You need cookieParser and a session store. But if you don't want to extend this ExpressJS functionality (this is what i understand from your message), you should manage your own sessions with a token or a secret temporary string.

Although I strongly advise you to use ExpressJS sessions, this is how you should do it without ExpressJS cookies.

  • On each login, create a unique token and store it for future lookup.
  • On each request, send that token from the client and check it on the server. Redirect to the login if the token is invalid

Here is the login code example:

app.post("/login", function(req, res) {
    if(req.body.username && req.body.password) {
        // check username and password
        if(authenticated) {
            // create a token and store it with the current date (if you want it to expire)
            var token = generateAndStoreRandomString(req.body.username);
            res.redirect("http://your.domain/path?token=" + token);
            return;
        }
        // Do something if username or password wrong
    }
    // Do something if no username or password
});

Now, on every request:

app.get("somePath", function(req, res) {
    if(!req.query.token) {
        res.redirect("http://your.domain/login");
        return;
    }
    // Check token in database, if it exists and it hasn't expired
    if(!authenticated) {
        res.redirect("http://your.domain/login");
        return;
    }
    // The user is authenticated. Do the actions required by "somePath"
});

Try to have a process clean up the expired tokens every once in a while, since they will add up eventually. If you want to use ExpressJS cookieParser and session store, there are a lot of articles and examples. Post another question if you are having troubles with those.

I shall repeat myself, try using ExpressJS sessions. This method can be easily hijacked if you use http instead of https.

Discussion courtesy of: randunel

It's pretty simple. ExpressJS is a super tiny framework that's build ontop of the basic http server within Node.js and connect, a node module.

To make an authentication system you would use sessions. First you need to call this line:

app.use(express.cookieSession());

Then you'll be able to use the req.session to store and load sessions.

app.post('/login', function(req, res) {
    if (req.session.username & req.session.password != null) {
       // Already logged in.
    } else {
       var q = db.query("SELECT * FROM `users` WHERE `username`='" + req.params.username + "' AND `password`='" + req.params.password + "'");

       if (q) {
          // Set the sessions.
          req.session.username = req.params.username;
          req.session.password = req.params.password;
       }
    }
});

A basic example. You would definitely have to sanitize the input and secure it, but it should get you started.

Discussion courtesy of: Daniel

This recipe can be found in it's original form on Stack Over Flow.