• Latest
  • Trending
User Authentication in NodeJS Using Passport and MongoDB

User Authentication in NodeJS Using Passport and MongoDB

March 9, 2022
Inaugural AfCFTA Conference on Women and Youth in Trade

Inaugural AfCFTA Conference on Women and Youth in Trade

September 6, 2022
Instagram fined €405m over children’s data privacy

Instagram fined €405m over children’s data privacy

September 6, 2022
8 Most Common Causes of a Data Breach

5.7bn data entries found exposed on Chinese VPN

August 18, 2022
Fibre optic interconnection linking Cameroon and Congo now operational

Fibre optic interconnection linking Cameroon and Congo now operational

July 15, 2022
Ericsson and MTN Rwandacell Discuss their Long-Term Partnership

Ericsson and MTN Rwandacell Discuss their Long-Term Partnership

July 15, 2022
Airtel Africa Purchases $42M Worth of Additional Spectrum

Airtel Africa Purchases $42M Worth of Additional Spectrum

July 15, 2022
Huawei steps up drive for Kenyan talent

Huawei steps up drive for Kenyan talent

July 15, 2022
TSMC predicts Q3 revenue boost thanks to increased iPhone 13 demand

TSMC predicts Q3 revenue boost thanks to increased iPhone 13 demand

July 15, 2022
Facebook to allow up to five profiles tied to one account

Facebook to allow up to five profiles tied to one account

July 15, 2022
Top 10 apps built and managed in Ghana

Top 10 apps built and managed in Ghana

July 15, 2022
MTN Group to Host the 2nd Edition of the MoMo API Hackathon

MTN Group to Host the 2nd Edition of the MoMo API Hackathon

July 15, 2022
KIOXIA Introduce JEDEC XFM Removable Storage with PCIe/NVMe Spec

KIOXIA Introduce JEDEC XFM Removable Storage with PCIe/NVMe Spec

July 15, 2022
  • Consumer Watch
  • Kids Page
  • Directory
  • Events
  • Reviews
Sunday, 5 February, 2023
  • Login
itechnewsonline.com
  • Home
  • Tech
  • Africa Tech
  • InfoSEC
  • Data Science
  • Data Storage
  • Business
  • Opinion
Subscription
Advertise
No Result
View All Result
itechnewsonline.com
No Result
View All Result

User Authentication in NodeJS Using Passport and MongoDB

User authentication is crucial for protecting sensitive information. Luckily, it's not difficult to implement this.

by ITECHNEWS
March 9, 2022
in Data Science, Leading Stories
0 0
0
User Authentication in NodeJS Using Passport and MongoDB

If you want to protect sensitive content in your Node application, you need a way to authenticate users. However, building your own authentication system is complex, and time-consuming and if not done correctly can introduce security vulnerabilities in your application. Third-party tools like Passport make authentication easier.

In this tutorial, you will learn how to implement authentication in Node using Passport and MongoDB.

YOU MAY ALSO LIKE

Inaugural AfCFTA Conference on Women and Youth in Trade

Instagram fined €405m over children’s data privacy

What Are Authentication and Authorization?

While authentication and authorization are sometimes used interchangeably, these two security concepts have different meanings. Authentication is the process of verifying a user is who they claim to be while authorization is the process of determining whether an authenticated user has access to certain parts of your application.

What Is Passport.js?

Passport.js (or Passport) is an authentication middleware for NodeJS that provides more than 500 strategies for authenticating users including passport-local which uses a username and password.

This tutorial uses passport-local and passport-jwt to secure routes.

How to Set Up User Authentication in NodeJS

Now you know a little about user authentication and Passport.js, we can look at how to set up authentication on NodeJS. Below, we’ve outlined the steps you’ll need to take.

Step 1: Set Up a Node Server

Create a folder named user-auth-nodejs and navigate to it using your terminal.

mkdir user-auth-nodejs

cd user-auth-nodejs

Next initialize package.json.

npm init

Since you will be using Express, a NodeJS backend framework, install it by running the following command.

npm i express

Now create a file, app.js, and add the following code to create the server.

const express = require("express");
const app = express();
const PORT = 3000;
app.listen(PORT, () => {
console.log(`Listening on port ${PORT}`);
});

 

Step 2: Set Up the Database

You need a database to store user data. You will use mongoose to create a MongoDB data schema that defines the structure and type of data you will store in the database. Since you are storing user data, create a user schema.

Install mongoose.

npm i mongoose

Create a new file, userModel.js, and add the following.

const mongoose = require('mongoose')
const {Schema} = mongoose
const UserSchema = new Schema ({
 email: {
 type: String,
 required: true
 },
 password: {
 type: String,
 required: true
 }
})
const UserModel = mongoose.model('user', UserSchema);
module.exports = UserModel;

 

Before storing the password, you need to encrypt it for security purposes. You will use bcryptjs, a very useful npm package that makes working with encrypted passwords easy.

Install bcryptjs.

npm i bcryptjs

Modify usermodel.js to encrypt the password before saving it to the database.

const mongoose = require('mongoose')
const bcrypt = require('bcryptjs');
const {Schema} = mongoose
 
const UserSchema = new Schema ({
...
})
UserSchema.pre('save', async function(next) {
 try {
 // check method of registration
 const user = this;
 if (!user.isModified('password')) next();
 // generate salt
 const salt = await bcrypt.genSalt(10);
 // hash the password
 const hashedPassword = await bcrypt.hash(this.password, salt);
 // replace plain text password with hashed password
 this.password = hashedPassword;
 next();
 } catch (error) {
 return next(error);
 }
 });
...
const User = mongoose.model('User', UserSchema);

Here you are using a pre save hook to modify the password before it is saved. The idea is to store the hash version of the password instead of the plain text password. A hash is a long complex string generated from a plain text string.

Use isModified to check whether the password is changing since you only need to hash new passwords. Next, generate a salt and pass it with the plain text password to the hash method to generate the hashed password. Finally, replace the plain text password with the hashed password in the database.

Create db.js and configure the database.

const mongoose = require("mongoose");
mongoose.Promise = global.Promise;
const dbUrl = "mongodb://localhost/user";
const connect = async () => {
 mongoose.connect(dbUrl, { useNewUrlParser: true, useUnifiedTopology: true });
 const db = mongoose.connection;
 db.on("error", () => {
 console.log("could not connect");
 });
 db.once("open", () => {
 console.log("> Successfully connected to database");
 });
};
module.exports = { connect };

In app.js, connect to the database.

// connect to db
const db = require('./db');
db.connect();

Step 3: Set Up Passport

Install Passport and passport-local. You will use these packages to register and login users.

npm i passport
npm i passport-local

Create a new file, passportConfig.js, and import passport-local and the userModel.js.

const LocalStraregy = require("passport-local").Strategy;
const User = require("./userModel");

Configure Passport to handle user registration.

const LocalStrategy = require("passport-local");
const User = require("./userModel");
module.exports = (passport) => {
 passport.use(
 "local-signup",
 new LocalStrategy(
 {
 usernameField: "email",
 passwordField: "password",
 },
 async (email, password, done) => {
 try {
 // check if user exists
 const userExists = await User.findOne({ "email": email });
 if (userExists) {
 return done(null, false)
 }
 // Create a new user with the user data provided
 const user = await User.create({ email, password });
 return done(null, user);
 } catch (error) {
 done(error);
 }
 }
 )
 );
}

In the above code, you are checking if the email is already in use. If the email does not exist, register the user. Note that you are also setting the username field to accept an email. By default, passport-local expects a username, so you need to tell it you are passing in an email instead.

Use passport-local to also handle user login.

module.exports = (passport) => {
 passport.use(
 "local-signup",
 new localStrategy(
 ...
 )
 );
passport.use(
 "local-login",
 new LocalStrategy(
 {
 usernameField: "email",
 passwordField: "password",
 },
 async (email, password, done) => {
 try {
 const user = await User.findOne({ email: email });
 if (!user) return done(null, false);
 const isMatch = await user.matchPassword(password);
 if (!isMatch)
 return done(null, false);
 // if passwords match return user
 return done(null, user);
 } catch (error) {
 console.log(error)
 return done(error, false);
 }
 }
 )
 );
};

Here, check whether the user exists in the database, and if they do, check if the password provided matches the one in the database. Note you also call the matchPassword() method on the user model so go to userModel.js file and add it.

UserSchema.methods.matchPassword = async function (password) {
 try {
 return await bcrypt.compare(password, this.password);
 } catch (error) {
 throw new Error(error);
 }
};

This method compares the password from the user and the one in the database and returns true if they match.

Step 4: Set Up Authentication Routes

You now need to create the endpoints to which users will send data. First up is the signup route which will accept the email and password of a new user.

In app.js, use the passport authentication middleware you just created to register the user.

app.post(
 "/auth/signup",
 passport.authenticate('local-signup', { session: false }),
 (req, res, next) => {
 // sign up
 res.json({
 user: req.user,
 });
 }
);

 

If successful, the signup route should return the created user.

User signup using Passport

Next, create the login route.

app.post(
 "/auth/login",
 passport.authenticate('local-login', { session: false }),
 (req, res, next) => {
 // login
 res.json({
 user: req.user,
 });
 }
);

Step 5: Add Protected Routes

So far, you have used Passport to create a middleware that registers a user in the database and another that allows a registered user to sign in. Next, you will create an authorization middleware to protect sensitive routes using a JSON web token(JWT). To implement JWT authorization, you need to:

  • Generate JWT token.
  • Pass the token to the user. The user will send it back in authorization requests.
  • Verify the token sent back by the user.

You will use the jsonwebtoken package to handle JWTs.

Run the following command to install it.

npm i jsonwebtoken

Next, generate a token for each user that successfully logs in.

In app.js, import jsonwebtoken and modify the login route like below.

app.post(
 "/auth/login",
 passport.authenticate('local-login', { session: false }),
 (req, res, next) => {
 // login
 jwt.sign({user: req.user}, 'secretKey', {expiresIn: '1h'}, (err, token) => {
 if(err) {
 return res.json({
 message: "Failed to login",
 token: null,
 });
 }
 res.json({
 token
 });
 })
 }
);

In a real-life application, you would use a more complicated secret key and store it in a configuration file.

The login route returns a token if successful.

Use passport-jwt to access protected routes.

npm i passport-jwt

In passportConfig.js, configure the passport-jwt.

const JwtStrategy = require("passport-jwt").Strategy;
const { ExtractJwt } = require("passport-jwt")
module.exports = (passport) => {
passport.use(
 "local-login",
 new LocalStrategy(
 ...
 );
passport.use(
 new JwtStrategy(
 {
 jwtFromRequest: ExtractJwt.fromHeader("authorization"),
 secretOrKey: "secretKey",
 },
 async (jwtPayload, done) => {
 try {
 // Extract user
 const user = jwtPayload.user;
 done(null, user);
 } catch (error) {
 done(error, false);
 }
 }
 )
 );
};

Notice you are extracting the JWT from the authorization header instead of the request body. This prevents hackers from intercepting a request and grabbing the token.

To see how passport-jwt guards routes, create a protected route in app.js.

app.get(
 "/user/protected",
 passport.authenticate("jwt", { session: false }),
 (req, res, next) => {
 res.json({user: req.user});
 }
);

Only a request with a valid JWT returns the user data.

User data from protected route
Source: MARY GATHONI
Via: makeuseof
Tags: Passport and MongoDB
ShareTweetShare
Plugin Install : Subscribe Push Notification need OneSignal plugin to be installed.

Search

No Result
View All Result

Recent News

Inaugural AfCFTA Conference on Women and Youth in Trade

Inaugural AfCFTA Conference on Women and Youth in Trade

September 6, 2022
Instagram fined €405m over children’s data privacy

Instagram fined €405m over children’s data privacy

September 6, 2022
8 Most Common Causes of a Data Breach

5.7bn data entries found exposed on Chinese VPN

August 18, 2022

About What We Do

itechnewsonline.com

We bring you the best Premium Tech News.

Recent News With Image

Inaugural AfCFTA Conference on Women and Youth in Trade

Inaugural AfCFTA Conference on Women and Youth in Trade

September 6, 2022
Instagram fined €405m over children’s data privacy

Instagram fined €405m over children’s data privacy

September 6, 2022

Recent News

  • Inaugural AfCFTA Conference on Women and Youth in Trade September 6, 2022
  • Instagram fined €405m over children’s data privacy September 6, 2022
  • 5.7bn data entries found exposed on Chinese VPN August 18, 2022
  • Fibre optic interconnection linking Cameroon and Congo now operational July 15, 2022
  • Home
  • InfoSec
  • Opinion
  • Africa Tech
  • Data Storage

© 2021-2022 iTechNewsOnline.Com - Powered by BackUPDataSystems

No Result
View All Result
  • Home
  • Tech
  • Africa Tech
  • InfoSEC
  • Data Science
  • Data Storage
  • Business
  • Opinion

© 2021-2022 iTechNewsOnline.Com - Powered by BackUPDataSystems

Welcome Back!

Login to your account below

Forgotten Password?

Retrieve your password

Please enter your username or email address to reset your password.

Log In
Go to mobile version