Tuesday, June 23 2020
In this tutorial, we are going to discuss about How to build Secure Authentication App using JWT in Node.JS and Express JS. JWT means JSON Web Token is a object that is safe approach to transfer data between two parties.
Click here to read about Authentication App with OAuth2.0 and Node.js
npm init npm install express jsonwebtoken bcryptjs body-parser cors mongoose env-cmd --save npm install nodemon --save-dev
After the installation and create following files and folders in your project directory.
touch app.js // Root Directory mkdir middleware mkdir models mkdir routes // Authnetication cd middleware touch auth.js // Database cd models touch db.js touch user.model.js //Routing cd routes touch user.route.js
Create a .env file inside root directory with following contents
PORT=4000 JWT_KEY=JwtAuthenticationApp2020 MONGODB_URI=mongodb://localhost:27017/bg_mongo
Before create a schema we have to make an connection with mongodb in /models/db.js file with following contents.
// MongoDB connection const mongoose = require('mongoose'); mongoose.Promise = global.Promise; mongoose.connect(process.env.MONGODB_URI, {useUnifiedTopology: true, useNewUrlParser: true, useCreateIndex: true}); const db = mongoose.connection; db.on('error', console.error.bind(console, 'MongoDB connection error'));
Create schema for users table in /models/user.model.js file with following contents
const mongoose = require('mongoose'); const validator = require('validator'); const Schema = mongoose.Schema; const userSchema = new Schema({ name: { type: String, required: true, trim: true, max: 65 }, email: { type: String, required: true, trim: true, unique: true, lowercase: true, max: 65, validator: value => { if (!validator.isEmail(value)) { throw new Error({ error: 'Invalid Email address' }); } } }, password: { type: String, required: true, trim: true, minlength: 8 } }); module.exports = mongoose.model('User', userSchema);
In app.js file with following contents
const express = require('express'); const bodyParser = require('body-parser'); const cors = require("cors"); const router = require('./routes/user.route'); require('dotenv').config(); require('./models/db'); const port = process.env.PORT; const app = express(); var corsOptions = { origin: "http://localhost:4000" }; app.use(cors(corsOptions)); app.use(bodyParser.json()); app.use(bodyParser.urlencoded({extended:false})); app.use('/', router); app.listen(port, () => { console.log(`Server running on port ${port}`) })
In /routes/user.route.js file with following contents
const router = require('express').Router(); const bcrypt = require('bcryptjs'); const jwt = require('jsonwebtoken'); const userModel = require('../models/user.model'); const auth = require('../middleware/auth');
Once included the packages, we makes below REST API calls.
HTTP /POST – user register
router.post('/user/register', (req, res, next) => { bcrypt.hash(req.body.password, 10).then((hash) => { const user = new userModel({ name: req.body.name, email: req.body.email, password: hash }); user.save().then((response) => { res.status(201).json({message: "User successfully created!", result: response}); }).catch(error => { res.status(500).json({error: error}); }) }); });
After that, Run nodemon app.js in the terminal. Goto Postman check register URL http://localhost:4000/user/register through /POST method.
HTTP /POST – user login
router.post('/user/login', (req, res, next) => { let getUser; userModel.findOne({ email: req.body.email }).then(user => { if (!user) { return res.status(401).json({message: "Authentication failed"}); } getUser = user; return bcrypt.compare(req.body.password, user.password); }).then(response => { if (!response) { return res.status(401).json({message: "Authentication failed"}); } let jwtToken = jwt.sign( { email: getUser.email,userId: getUser._id, }, process.env.JWT_KEY, { expiresIn: "1h" } ); res.status(200).json({ token: jwtToken, expiresIn: 3600, data: getUser }); }).catch(error => { return res.status(401).json({message: "Authentication failed"}); }) });
After that, Run nodemon app.js in the terminal. Goto Postman check login URL http://localhost:4000/user/login through /POST method.
After logged we make an API for profile page.
Before making this API we need to create authentication function to verify that connection using in /middleware/auth.js file with following contents
const jwt = require('jsonwebtoken'); const userModel = require('../models/user.model'); const auth = (req, res, next) => { const authHeader = req.headers.authorization; if (authHeader) { const token = authHeader.split(' ')[1]; data = jwt.verify(token, process.env.JWT_KEY); userModel.findOne({ _id: data.userId, }).then(user => { if (!user) { res.status(401).json({message: "Authentication failed"}); } next(); }).catch(error => { return res.status(401).json({message: "Authentication failed"}); }); } else { return res.status(401).json({message: "Authentication missing"}); } }; module.exports = auth;
Update the below codes in /routes/user.route.js file for user profile page.
router.get('/user/me/:id', auth, (req, res, next) => { userModel.findById(req.params.id, (error, data) => { if (error) { return next(error); } else { res.status(200).json({result: data}); } }); });
After that, Run nodemon app.js in the terminal. Goto Postman check this profile URL http://localhost:4000/user/me/{_id} through /GET method.
Thanks for reading this tutorial. Please share this post with others.