MEAN stack user authentication example

Published Jul 18, 2017Last updated Sep 08, 2017
MEAN stack user authentication example

MEAN stack user authentication example – I’ve split the login and registration pages out from the angular application in order to secure access to the angular client files, so all front end angular files (including javascript, css, images etc) are only available to authenticated users. To run MEAN stack applications locally you need NodeJS installed and MongoDB running on your system.

It’s also possible to include the login and registration pages within the angular application and allow public access to the angular client files, this is how I’ve built previous examples and is fine as long as you don’t have any sensitive data stored in your client files. The main benefit of securing the client files is just a bit of extra piece of mind that you’re not going to accidentally leak any secure information in your angular app files.

The express js application is structured using an MVC-ish pattern, there are controllers and views but rather than models I’ve gone with a services layer for data access & business logic. The services use mongoskin as the mongodb driver, it’s a thin wrapper for the native mongodb driver that provides a simpler interface for performing CRUD operations.

we have also develop Single page application user authentication in angularjs. just check here to get the free source code.

Run the project

Once you’ve downloaded the code you can run the command ‘npm install’ from the project root folder (where the package.json file is located) to download all node package dependencies.

Then run ‘node server.js’ from the same location to start the web server and browse to http://localhost:3000 to access the application.

MEAN stack user authentication example

Step 1:
First create index.html file.

  <!DOCTYPE html>
  <html>
  <head>
    <meta charset="utf-8" />
    <title>MEAN Stack User Registration and Login Example Application</title>

    <link href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css" rel="stylesheet" />
    <link href="app-content/app.css" rel="stylesheet" />
</head>
<body class="container">
    <!-- header -->
    <header>
        <ul class="nav nav-tabs">
            <li ng-class="{active: activeTab === 'home'}"><a ui-sref="home">Home</a></li>
            <li ng-class="{active: activeTab === 'account'}"><a ui-sref="account">Account</a></li>
            <li><a href="/login" target="_self">Logout</a></li>
        </ul>
        <div class="flash-message" ng-if="flash">
            <div class="{{'alert alert-' + flash.type}}" ng-bind="flash.message"></div>
        </div>
    </header>

    <!-- main -->
    <main ui-view></main>

    <!-- footer -->
    <footer></footer>

    <!-- external scripts -->
    <script src="//ajax.googleapis.com/ajax/libs/jquery/2.1.4/jquery.min.js"></script>
    <script src="//ajax.googleapis.com/ajax/libs/angularjs/1.4.7/angular.min.js"></script>
    <script src="//cdnjs.cloudflare.com/ajax/libs/angular-ui-router/0.2.15/angular-ui-router.min.js"></script>

    <!-- application scripts -->
    <script src="app.js"></script>
    <script src="app-services/user.service.js"></script>
    <script src="app-services/flash.service.js"></script>
    <script src="home/index.controller.js"></script>
    <script src="account/index.controller.js"></script>
</body>
</html>

Step 2:

Express/NodeJS Users API Controller

The express users api controller defines the routes responsible for user related operations such as authentication, registration, retrieving, updating and deleting user data.

var config = require('config.json');
var express = require('express');
var router = express.Router();
var userService = require('services/user.service');

// routes
router.post('/authenticate', authenticateUser);
router.post('/register', registerUser);
router.get('/current', getCurrentUser);
router.put('/:_id', updateUser);
router.delete('/:_id', deleteUser);

module.exports = router;

function authenticateUser(req, res) {
    userService.authenticate(req.body.username, req.body.password)
        .then(function (token) {
            if (token) {
                // authentication successful
                res.send({ token: token });
            } else {
                // authentication failed
                res.sendStatus(401);
            }
        })
        .catch(function (err) {
            res.status(400).send(err);
        });
}

function registerUser(req, res) {
    userService.create(req.body)
        .then(function () {
            res.sendStatus(200);
        })
        .catch(function (err) {
            res.status(400).send(err);
        });
}

function getCurrentUser(req, res) {
    userService.getById(req.user.sub)
        .then(function (user) {
            if (user) {
                res.send(user);
            } else {
                res.sendStatus(404);
            }
        })
        .catch(function (err) {
            res.status(400).send(err);
        });
}

function updateUser(req, res) {
    var userId = req.user.sub;
    if (req.params._id !== userId) {
        // can only update own account
        return res.status(401).send('You can only update your own account');
    }

    userService.update(userId, req.body)
        .then(function () {
            res.sendStatus(200);
        })
        .catch(function (err) {
            res.status(400).send(err);
        });
}

function deleteUser(req, res) {
    var userId = req.user.sub;
    if (req.params._id !== userId) {
        // can only delete own account
        return res.status(401).send('You can only delete your own account');
    }

    userService.delete(userId)
        .then(function () {
            res.sendStatus(200);
        })
        .catch(function (err) {
            res.status(400).send(err);
        });
}

Step 3:

Express/NodeJS App Controller

The express app controller controls access to the angular app client files. It uses session/cookie authentication to secure the angular files, and also exposes a JWT token to be used by the angular app to make authenticated api requests.

var express = require('express');
var router = express.Router();

// use session auth to secure the angular app files
router.use('/', function (req, res, next) {
    if (req.path !== '/login' && !req.session.token) {
        return res.redirect('/login?returnUrl=' + encodeURIComponent('/app' + req.path));
    }

    next();
});

// make JWT token available to angular app
router.get('/token', function (req, res) {
    res.send(req.session.token);
});

// serve angular app files from the '/app' route
router.use('/', express.static('app'));

module.exports = router;

Connect the MongoDB

The express config file contains configuration data used by the nodejs application.

{
    "connectionString": "mongodb://localhost:27017/mean-stack-registration-login-example",
    "apiUrl":  "http://localhost:3000/api",
    "secret": "REPLACE THIS WITH YOUR OWN SECRET, IT CAN BE ANY STRING"
}
Discover and read more posts from Sarika Aerolla
get started
Enjoy this post?

Leave a like and comment for Sarika

2
2