TOKEN BASED AUTHENTICATION FOR MEAN STACK APPS – PART 1
Creating independent frontend and backend applications makes scalability easy. Building your backend as an API and consuming it with frontend components makes development easily maintainable and allows distribution across different servers when your app grows very large.
SETTING UP YOUR ENVIRONMENT
Today, we’ll build a simple app that demonstrates how to implement token-based authentication in mean stack apps. This is one way of going about it amidst many others.
MEAN – Mongodb( Our Database ), Express ( Node.js Framework ), AngularJs ( Frontend Framework ), Nodejs( Server-side Language )
Let’s Jump Right In
Let’s create a new Node.js application called auth-meanapp. Make sure you have npm installed already. Create a directory named auth-meanapp, this is where our application will reside.
Now, create a package.json file by running this command like so:
1 |
npm init |
Go through the instructions, fill the required details. name, version, description, entry point, test command, git repository, keywords, author, license . It’s actually optional, you could just press enter continuously to skip it till it’s completed.
Then run the following command from your terminal like so:
1 |
npm install express mongoose morgan dotenv lodash cors jsonwebtoken body-parser gravatar --save |
express – Fast minimalistic web framework for node.js
mongoose – It is a MongoDB object modeling tool designed to work in an asynchronous environment.
morgan – node.js module that enables detailed logging
dotenv – loads environment variables from .env in to ENV (process.env).
lodash – node.js module for working with data structures and functions
cors – node.js module for allowing cross origin request on your backend
gravatar – node.js module for fetching avatars from emails during user sign-ups
jsonwebtoken – node.js module for implementing json web tokens
body-parser – node.js middleware for parsing body form requests
bcrypt – A hashing library for node.js
— save is to ensure that it’s details are saved in our package.json file.
Your package.json file should look something similar to this:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 |
{ "name": "auth-meanapp", "version": "1.0.0", "description": "", "main": "index.js", "scripts": { "test": "echo "Error: no test specified" && exit 1" }, "author": "", "license": "ISC", "dependencies": { "body-parser": "^1.13.1", "cors": "^2.7.1", "dotenv": "^1.2.0", "express": "^4.13.0", "gravatar": "^1.1.1", "jsonwebtoken": "^5.0.2", "lodash": "^3.10.0", "mongoose": "^4.0.6", "morgan": "^1.6.0" } } |
This is the folder structure of our app:
auth-meanapp
1 2 3 4 5 6 7 8 9 10 11 12 |
-------------- config ------------------- secrets.js ------------------- testdb.js ------------------- tokenMiddleware.js -------------- node_modules -------------- public ------------------ index.html -------------- server ------------------ controllers ---------------------- user.server.controller.js ------------------ models ---------------------- user.server.model.js |
The next step is to create .env file so that node.js can properly pull environment variables for the app.
My .env file looks like this:
.env
1 2 3 4 5 |
MONGODB=mongodb://localhost/auth-mean NODE_ENV=development SESSION_SECRET=meanprosper |
Note: Make sure you have mongodb installed on your system.
Next, let’s create a server.js file in the root of our folder. This is the main entry and starting point for our application.
server.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 |
require('dotenv').load(); // loads the environment variables in the .env file var express = require('express'), jwt = require('jsonwebtoken'); morgan = require('morgan'), bodyParser = require('body-parser'), mongoose = require('mongoose'), User = require('./server/models/user.server.model'), cors = require('cors'), secrets = require('./config/secrets'), testdb = require('./config/testdb'), route = require('./server/routes'); var port = process.env.PORT || 3000; /** * Connect to MongoDB. */ testdb.dbconnect(); /** * Create Express server. */ var app = express(); /** * Express configuration. */ app.use(cors()); // allows cross origin request app.use(morgan('dev')); // for logging of every request made in the application app.use(bodyParser.urlencoded({extended: true})); //use bodyParser for request and parsing info app.use(bodyParser.json()); app.use(express.static( __dirname + '/public')); //use to serve static files like favicon, css, angular and the rest /** * Routes Configuration */ route(app); //configure any route whatsoever to redirect to angular app.get('*', function(req, res) { /** frontend routes ========================================================= * route to handle all angular requests * load the single view file (angular will handle the page changes on the front-end) **/ res.sendFile(__dirname + '/public/index.html' ); }); /** * Start Express server. */ app.listen( port, function(){ console.log("Server Listening on port ", port ); }); |
secrets.js
1 2 3 4 5 6 7 8 9 10 11 12 13 |
module.exports = { db: process.env.MONGODB || process.env.MONGOHQ_URL, sessionSecret: process.env.SESSION_SECRET }; |
testdb.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
var mongoose = require('mongoose'), secrets = require('./secrets'); var db = mongoose.connection; mongoose.connect(secrets.db); module.exports = { dbconnect: function(){ db.on('error', console.error.bind( console, 'MongoDB Connection Error. Please make sure that MongoDB is running.')); db.once('open', function callback(){ console.log('auth-meanapp db opened'); }); } }; |
tokenMiddleware.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 |
var jwt = require('jsonwebtoken'), secrets = require('./secrets'); module.exports = function(req, res, next){ // check header parameters for token var token = req.headers['x-access-token']; if(token) { // verifies secret and checks exp jwt.verify(token, secrets.sessionSecret, function(err, decoded) { if(err) { return res.json({ message: 'Unauthorized Access. Mismatched token.' }); } else { // if everything is good, save to request for use in other routes req.decoded = decoded; next(); } }); } else { // if there is no token return an error return res.status(403).json({ message: 'Unauthorized Access' }); } }; |
routes.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
var User = require('./controllers/user.server.controller'), jwt = require('jsonwebtoken'), secrets = require('../config/secrets'), verifyToken = require('../config/tokenMiddleware'); module.exports = function(app) { }; |
If you have created all the files mentioned above, run the application like so:
1 |
nodemon server.js |
NOTE: Install nodemon globally, if you don’t have it..run npm install nodemon -g on your terminal.
nodemon watches for file changes and automatically restarts your node application.
The application would be served on port 3000 and it’ll show an empty webpage.
Thanks for reading, we’ll continue in the next post tomorrow!

- How to build your own Youtube – Part 10 - August 1, 2016
- How to build your own Youtube – Part 9 - July 25, 2016
- How to build your own Youtube – Part 8 - July 23, 2016
- How to build your own Youtube – Part 6 - July 6, 2016
- Introducing Laravel Password v1.0 - July 3, 2016
- How to build your own Youtube – Part 5 - June 28, 2016
- How to build your own Youtube – Part 4 - June 23, 2016
- How to build your own Youtube – Part 3 - June 15, 2016
- How to build your own Youtube – Part 2 - June 8, 2016
- How to build your own Youtube – Part 1 - June 1, 2016