Welcome folks today in this blog post we will be building the jwt
authentication system in node.js and express using mongodb
database in browser using javascript. All the full source code of the application is shown below.
BUY FULL SOURCE CODE
Get Started
In order to get started you need to make a new node.js
project using the below command as shown below
npm init -y
And now after that we need to install all the dependencies
which are needed for this project as shown below
npm i express
npm i jsonwebtoken
npm i mongoose
npm i bcrypt
npm i cookie-parser
npm i validator
npm i ejs
Express
: This will be the web server which we will be using for our application
mongoose
: It will be dependency which we will be using for interacting with the Mongodb
database
bcrypt
: This will be used for hashing
the passwords
validator
: This will be used for validating the data
ejs
: This will be the view
engine used for the application.
jsonwebtoken
This library will generate and verify the json
web token and let users login into the protected routes.
cookie-parser
: This dependency will allow users to create and read cookies inside the express application
Directory Structure
At the end of this app this will be the directory
structure you will be having as shown below
As you can see in the above directory structure of the project we are following the MVC
approach which ensures all the code will be divided into their respective modules. Model will be the data
used inside the application. View will be the different views
used to render the app and the Controller
will be the actual logic which will be used to make the Auth
system. Apart from that we have also the Routes
folder which will consist of all the routes
used inside the express app. And middlewares folder will contain all the middleware or other functions used to make the app.
Starting a Basic Express App
Now guys we need to create the index.js
file inside the root directory which will be the starting point of the project. And copy paste the below code to start a basic express app. And also we will be connecting to the Mongdb
database as shown below
index.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 |
const express = require("express"); const mongoose = require("mongoose"); const cookieParser = require("cookie-parser"); const app = express(); // middleware app.use(express.static("public")); app.use(express.json()); app.use(cookieParser()); // view engine app.set("view engine", "ejs"); // database connection const dbURI = "mongodb://localhost:27017/node-auth"; mongoose .connect(dbURI, { useNewUrlParser: true, useUnifiedTopology: true, useCreateIndex: true, }) .then((result) => app.listen(3000)) .catch((err) => console.log(err)); |
As you can see we are importing the mongoose
module and then using the connect()
method to connect to the database here you need to pass the database URL
and then inside the callback function we are starting the express app at port 3000. And also we are passing different middlewares such as cookie-parser which is used to create and read cookies. And also we are making the public directory
as static. Now you also need to create the public
directory to hold the static files. We are also setting the view engine
as ejs.
Defining the Views
Now guys inside the index.js
file we need to define two routes which is specifically there to load the home page
and the dashboard
page as shown below
1 2 3 4 |
app.get("/", (req, res) => { res.render("login"); }); app.get("/dashboard",(req, res) => res.render("dashboard")); |
Now we need to create the views
folder and create this above files to allow the user to see the login
page when he/she goes to the home
page and see the dashboard page as well
views/login.ejs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
<%- include('partials/header'); -%> <form> <h2>Login</h2> <label for="email">Email</label> <input type="text" name="email" /> <div class="email error"></div> <label for="password">Password</label> <input type="password" name="password" /> <div class="password error"></div> <button>login</button> </form> </body> </html> |
As you can see at the top we are loading the dynamic
header file with the help of ejs
and after that we have a basic html5
form where we have two fields to allow the user to enter the email
and password and login
button. Now we need to create the partials
folder and inside it define the header.ejs
file as shown below
partials/header.ejs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
<html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> <link rel="stylesheet" href="/styles.css"> </head> <body> <nav> <h1><a href="/">JWT Auth</a></h1> <ul> <li><a href="/login">Log in</a></li> <li><a href="/signup" class="btn">Sign up</a></li> </ul> </nav> |
As you can see we are including the styles.css
file at the top and then we have a simple nav
where we have two buttons
of login and signup.
Defining the CSS
Now we need to define the css
for the login and register forms. For this inside the public folder create a styles.css
file and copy paste the below code
public/styles.css
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 108 109 110 111 112 113 114 |
/* google fonts */ @import url('https://fonts.googleapis.com/css2?family=Quicksand:wght@300;400;500;600;700&display=swap'); body{ margin: 20px 40px; font-size: 1.2rem; letter-spacing: 1px; background: #fafafa; } h1, h2, h3, h4, ul, li, a, p, input, label, button, div, footer{ margin: 0; padding: 0; font-family: 'Quicksand', sans-serif; color: #444; } ul{ list-style-type: none; } a{ text-decoration: none; } nav{ display: flex; justify-content: space-between; align-items: flex-end; margin-bottom: 120px; } nav ul{ display: flex; align-items: center; } nav li{ margin-left: 20px; } nav li a{ text-transform: uppercase; font-weight: 700; font-size: 0.8em; display: block; padding: 10px 16px; letter-spacing: 2px; } .btn{ border-radius: 36px; background: #FEE996; } form h2{ font-size: 2.4em; font-weight: 900; margin-bottom: 40px; } form{ width: 360px; margin: 0 auto; padding: 30px; box-shadow: 1px 2px 3px rgba(0,0,0,0.1); border-radius: 10px; background: white; } input{ padding: 10px 12px; border-radius: 4px; border: 1px solid #ddd; font-size: 1em; width: 100%; } label{ display: block; margin: 20px 0 10px; } button{ margin-top: 30px; border-radius: 36px; background: #FEE996; border:0; text-transform: uppercase; font-weight: 700; font-size: 0.8em; display: block; padding: 10px 16px; letter-spacing: 2px; } .error{ color: #ff0099; margin: 10px 2px; font-size: 0.8em; font-weight: bold; } header{ display: flex; align-items: center; } header img{ width: 250px; margin-right: 40px; } header h2{ font-size: 3em; margin-bottom: 10px; } header h3{ font-size: 1.6em; margin-bottom: 10px; margin-left: 2px; color: #999; } header .btn{ margin-top: 20px; padding: 12px 18px; text-transform: uppercase; font-weight: bold; display: inline-block; font-size: 0.8em; } |
And now if you see the login
form it will look something as shown below
Similarly we need to create the register.ejs
file and copy paste the following code which is shown below
signup.ejs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
<%- include('partials/header'); -%> <form> <h2>Sign up</h2> <label for="email">Email</label> <input type="text" name="email" required /> <div class="email error"></div> <label for="password">Password</label> <input type="password" name="password" required /> <div class="password error"></div> <button>Sign up</button> </form> </body> </html> |
Now we will be creating the dashboard.ejs
file which will be the protected page where only the authenticated
users can access and see that page as shown below
dashboard.ejs
1 2 3 |
<%- include('partials/header'); -%> <h1>This is the dashboard Account Page</h1> |
Initializing Routes & Controllers
Now we will be initializing the different routes
and controllers
necessary for this auth system. For this you need to create the routes
folder and inside it you need to create authRoutes.js
file and also create a controllers
folder and inside it create a authController.js
file as shown below
routes/authRoutes.js
1 2 3 4 5 6 7 8 9 10 11 |
const { Router } = require('express'); const authController = require('../controllers/authController'); const router = Router(); router.get('/signup', authController.signup_get); router.post('/signup', authController.signup_post); router.post('/login', authController.login_post); router.get('/logout', authController.logout_get); module.exports = router; |
As you can see we are having different routes
or endpoints for different operations such as get
request to login and signup pages using the express
router. And same for post method as well. And here we are importing the controller
file at the top and then using the methods defined in it in the routes. Now we need to define the controller
file as well. Lastly here we are exporting the router from this file.
controllers/authController.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
// controller actions module.exports.signup_get = (req, res) => { res.render('signup'); } module.exports.signup_post = async (req, res) => { res.send('new signup'); } module.exports.login_get = (req,res) => { res.render('login') } module.exports.login_post = async (req, res) => { res.send('user login'); } |
As you can see in the above code we have defined all the four methods
that we have used inside the routes
file for now we are just returning the simple
messages for the post request. But later on we will be registering and logging the users. For the get requests we are rendering the `
Now at last we can include the authRoutes.js
file inside the app.js
file as shown below
app.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 |
const express = require('express'); const mongoose = require('mongoose'); const authRoutes = require('./routes/authRoutes'); const app = express(); // middleware app.use(express.static('public')); app.use(authRoutes); // view engine app.set('view engine', 'ejs'); // database connection const dbURI = "mongodb://localhost:27017/node-auth"; mongoose .connect(dbURI, { useNewUrlParser: true, useUnifiedTopology: true, useCreateIndex: true, }) .then((result) => app.listen(3000)) .catch((err) => console.log(err)); // routes app.get('/', (req, res) => res.render('login')); app.get('/dashboard', (req, res) => res.render('dashboard')); |
As you can see we are importing the file at the top and then we are passing it as a middleware using the use()
method.
Defining the Model & Schema
Now guys we will be defining the models
and the schema
which will be used for this auth system. For this you need to make the models
folder and create a User.js
file as shown below
models/User.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
const mongoose = require('mongoose'); const userSchema = new mongoose.Schema({ email: { type: String, required: true, unique: true, lowercase: true, }, password: { type: String, required: true, minlength: 6, } }); const User = mongoose.model('user', userSchema); module.exports = User; |
As you can see we are importing the mongoose
library at the top and then we are using the Schema
method to define the schema
which consists of email and password fields. And now we are also passing filters and validators for the data. And lastly we are using the model()
method to create the table
and also passing the schema which is defined earlier.
Inserting the User in MongoDB
Now guys after defining the model
file we can import that file inside the controller and define the code of post
method of login and signup routes as shown below
controllers/authController.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 |
const User = require("../models/User"); // controller actions module.exports.signup_get = (req, res) => { res.render('signup'); } module.exports.signup_post = async (req, res) => { const { email, password } = req.body; try { const user = await User.create({ email, password }); res.status(201).json(user); } catch(err) { console.log(err); res.status(400).send('error, user not created'); } } module.exports.login_post = async (req, res) => { const { email, password } = req.body; console.log(email, password); res.send('user login'); } |
As you can see we are retrieving the json
data passed by the user inside the post
requests and extracting the email
and password properties and then we are using the User.create()
method to insert the email and the password into the Mongo Database. And then we are sending the json
response back to the client.
Defining Custom Errors & Validating Data
Now inside the models
file we can add our own custom
error messages with the help of mongoose library as shown below
models/User.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
const mongoose = require('mongoose'); const { isEmail } = require('validator'); const userSchema = new mongoose.Schema({ email: { type: String, required: [true, 'Please enter an email'], unique: true, lowercase: true, validate: [isEmail, 'Please enter a valid email'] }, password: { type: String, required: [true, 'Please enter a password'], minlength: [6, 'Minimum password length is 6 characters'], } }); const User = mongoose.model('user', userSchema); module.exports = User; |
Returning Errors as JSON to the Client
Now guys we can return the errors
if user writes invalid data in the form of json
to the client. For this you need to update the code inside the controller
file as shown below
controllers/authController.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 |
const User = require("../models/User"); // handle errors const handleErrors = (err) => { console.log(err.message, err.code); let errors = { email: '', password: '' }; // incorrect email if (err.message === 'incorrect email') { errors.email = 'That email is not registered'; } // incorrect password if (err.message === 'incorrect password') { errors.password = 'That password is incorrect'; } // duplicate email error if (err.code === 11000) { errors.email = 'that email is already registered'; return errors; } // validation errors if (err.message.includes('user validation failed')) { // console.log(err); Object.values(err.errors).forEach(({ properties }) => { // console.log(val); // console.log(properties); errors[properties.path] = properties.message; }); } return errors; } // controller actions module.exports.signup_get = (req, res) => { res.render('signup'); } module.exports.signup_post = async (req, res) => { const { email, password } = req.body; try { const user = await User.create({ email, password }); res.status(201).json(user); } catch(err) { const errors = handleErrors(err); res.status(400).json({ errors }); } } module.exports.login_post = async (req, res) => { const { email, password } = req.body; console.log(email, password); res.send('user login'); } |
As you can see we have define a separate function which is called handleErrors()
and inside it we are extracting the error code
and the actual error message and then storing it inside the error
object and returning it. And then we are using the json()
method to send the errors.
Hashing the Passwords
Now guys we will be hashing
the plain text passwords that the user will submit for this we will be importing the bcrypt
module. So we need to modify the code of the model
file as shown below
models/User.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 |
const mongoose = require('mongoose'); const { isEmail } = require('validator'); const bcrypt = require('bcrypt'); const userSchema = new mongoose.Schema({ email: { type: String, required: [true, 'Please enter an email'], unique: true, lowercase: true, validate: [isEmail, 'Please enter a valid email'] }, password: { type: String, required: [true, 'Please enter a password'], minlength: [6, 'Minimum password length is 6 characters'], } }); // fire a function before doc saved to db userSchema.pre('save', async function(next) { const salt = await bcrypt.genSalt(); this.password = await bcrypt.hash(this.password, salt); next(); }); const User = mongoose.model('user', userSchema); module.exports = User; |
As you can see we are using the mongoose
hooks function which is pre()
it gets called everytime before when we save the data to the mongodb database. So here we are hashing the password
using the bcrypt library.
Adding the Cookie-Parser Middleware
Now we need to import the cookie-parser
library at the top and then we are passing the cookie-parser
middleware to the express app inside the index.js
file as shown below
index.js
1 2 3 4 5 |
const cookieParser = require("cookie-parser"); const app = express(); app.use(cookieParser()); |
Making the Login & Register HTML5 Forms
Now guys we will be using the html5
forms to allow the user to register
and login
. For this first of all we need to go authController.js
file and copy paste the signUp
code
controllers/authController.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 |
const User = require("../models/User"); const jwt = require('jsonwebtoken'); // create json web token const maxAge = 3 * 24 * 60 * 60; const createToken = (id) => { return jwt.sign({ id }, 'secret', { expiresIn: maxAge }); }; module.exports.signup_post = async (req, res) => { const { email, password } = req.body; try { const user = await User.create({ email, password }); const token = createToken(user._id); res.cookie('jwt', token, { httpOnly: true, maxAge: maxAge * 1000 }); res.status(201).json({ user: user._id }); } catch(err) { const errors = handleErrors(err); res.status(400).json({ errors }); } } |
As you can see we are importing the jsonwebtoken
library at the top and then we are creating a new user
using the create()
method and then we are creating the jwt
token and also passing the max_age
for it. And then we are setting the token in the cookie
.
And now we need to add the below ejs
code inside the signup.ejs
file as shown below
views/signup.ejs
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 |
<%- include('partials/header'); -%> <form action="/signup"> <h2>Sign up</h2> <label for="email">Email</label> <input type="text" name="email" required /> <div class="email error"></div> <label for="password">Password</label> <input type="password" name="password" required /> <div class="password error"></div> <button>Sign up</button> </form> <script> const form = document.querySelector('form'); const emailError = document.querySelector('.email.error'); const passwordError = document.querySelector('.password.error'); form.addEventListener('submit', async (e) => { e.preventDefault(); // reset errors emailError.textContent = ''; passwordError.textContent = ''; // get values const email = form.email.value; const password = form.password.value; try { const res = await fetch('/signup', { method: 'POST', body: JSON.stringify({ email, password }), headers: {'Content-Type': 'application/json'} }); const data = await res.json(); console.log(data); if (data.errors) { emailError.textContent = data.errors.email; passwordError.textContent = data.errors.password; } if (data.user) { location.assign('/dashboard'); } } catch (err) { console.log(err); } }); </script> <%- include('partials/footer'); -%> |
As you can see we are adding the javascript
code to the form and inside it we are taking the values submitted by the user and then we are making the post
request to the /signup
route. We are making the fetch request to the backend and then we are passing the headers
and also inside the body we are passing the email
and the password
. And also we are showing the validation errors as well from the json
response coming back from the server. And also we are redirecting the user to the dashboard
page.
Now we need to do the same
thing for the login
form as well. For this we need to edit the login.ejs
file as shown below
Now before we write the html code for the login
form we do need to write the code for comparing the password
for the login form. If password is correct or not. For this we will be comparing the hashes
of the password. For this we need to go to models/User.js
file and add this code
models/User.js
1 2 3 4 5 6 7 8 9 10 11 12 |
// static method to login user userSchema.statics.login = async function(email, password) { const user = await this.findOne({ email }); if (user) { const auth = await bcrypt.compare(password, user.password); if (auth) { return user; } throw Error('incorrect password'); } throw Error('incorrect email'); }; |
As you can see we have added the static
method of login
to the mongoDB Schema object. And inside it we are finding the user
using the email provided and then we are comparing the hashes
of the password.
And now we need to add the below code inside the authController.js
file as shown below
controllers/authController.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 |
const User = require("../models/User"); const jwt = require('jsonwebtoken'); // create json web token const maxAge = 3 * 24 * 60 * 60; const createToken = (id) => { return jwt.sign({ id }, 'secret', { expiresIn: maxAge }); }; module.exports.login_post = async (req, res) => { const { email, password } = req.body; try { const user = await User.login(email, password); const token = createToken(user._id); res.cookie('jwt', token, { httpOnly: true, maxAge: maxAge * 1000 }); res.status(200).json({ user: user._id }); } catch (err) { const errors = handleErrors(err); res.status(400).json({ errors }); } } |
As you can see in the above code we are adding the login
method we are using the login()
method of the model and then we are creating the jwt
token and then we are inserting the token inside the cookie.
And now we need to add the ejs
code inside the login.ejs
file as shown below
views/login.ejs
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 |
<%- include('partials/header'); -%> <form action="/signup"> <h2>Login</h2> <label for="email">Email</label> <input type="text" name="email" /> <div class="email error"></div> <label for="password">Password</label> <input type="password" name="password" /> <div class="password error"></div> <button>login</button> </form> <script> const form = document.querySelector('form'); const emailError = document.querySelector('.email.error'); const passwordError = document.querySelector('.password.error'); form.addEventListener('submit', async (e) => { e.preventDefault(); // reset errors emailError.textContent = ''; passwordError.textContent = ''; // get values const email = form.email.value; const password = form.password.value; try { const res = await fetch('/login', { method: 'POST', body: JSON.stringify({ email, password }), headers: {'Content-Type': 'application/json'} }); const data = await res.json(); console.log(data); if (data.errors) { emailError.textContent = data.errors.email; passwordError.textContent = data.errors.password; } if (data.user) { location.assign('/dashboard'); } } catch (err) { console.log(err); } }); </script> </body> </html> |
As you can see we are once again making a post
request using the fetch api and then sending the email
and password
to the /login
route and then we are also showing the validation
errors as well. And then redirecting to the /dashboard
page when the user fills out the correct details.
Adding Auth Middlewares
Now we will be adding the auth
middlewares which will be necessary to show the user
details inside the dashboard page and also we are checking if the jwt token
is present inside the cookie or not. Now we need to create the middlewares
folder and inside it we need to make the authMiddleware.js
file
middlewares/authMiddleware.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 |
const jwt = require('jsonwebtoken'); const User = require('../models/User'); const requireAuth = (req, res, next) => { const token = req.cookies.jwt; // check json web token exists & is verified if (token) { jwt.verify(token, 'secret', (err, decodedToken) => { if (err) { console.log(err.message); res.redirect('/login'); } else { console.log(decodedToken); next(); } }); } else { res.redirect('/login'); } }; // check current user const checkUser = (req, res, next) => { const token = req.cookies.jwt; if (token) { jwt.verify(token, 'secret', async (err, decodedToken) => { if (err) { res.locals.user = null; next(); } else { let user = await User.findById(decodedToken.id); res.locals.user = user; next(); } }); } else { res.locals.user = null; next(); } }; module.exports = { requireAuth, checkUser }; |
As you can see we are defining two methods in which we check the current
user if the jwt
token is present inside the cookie or not and then we are verifying the token using the verify()
method with the secret. And then we are setting the user to the res.locals
property so that we can show the details inside the dashboard
page. And then we have the requireAuth()
method in which we redirect the user to the /dashboard
page if the token is present inside the cookie.
Now we need to add the middlewares
inside the index.js
file as shown below
index.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 |
const express = require("express"); const mongoose = require("mongoose"); const jwt = require('jsonwebtoken') const authRoutes = require("./routes/authRoutes"); const cookieParser = require("cookie-parser"); const { requireAuth, checkUser } = require("./middleware/authMiddleware"); const app = express(); // middleware app.use(express.static("public")); app.use(express.json()); app.use(cookieParser()); // view engine app.set("view engine", "ejs"); // database connection const dbURI = "mongodb://localhost:27017/node-auth"; mongoose .connect(dbURI, { useNewUrlParser: true, useUnifiedTopology: true, useCreateIndex: true, }) .then((result) => app.listen(3000)) .catch((err) => console.log(err)); // routes app.get("*", checkUser); app.get("/", (req, res) => { const token = req.cookies.jwt; if (token) { jwt.verify(token, "secret", (err, decodedToken) => { if (err) { res.render('login') } else { res.render('dashboard') } }); } else { res.render("login"); } }); app.get("/dashboard", requireAuth, (req, res) => res.render("dashboard")); app.use(authRoutes); |
Showing User Details in Dashboard
Now we need to go to partials/header.ejs
file and inside it we will be showing the user details and the logout button using some conditional
rendering with the help of the ejs code as shown below
partials/header.ejs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
<html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> <link rel="stylesheet" href="/styles.css"> </head> <body> <nav> <h1><a href="/">JWT Auth</a></h1> <ul> <% if (user) { %> <li>Welcome, <%= user.email %></li> <li><a href="/logout">Log out</a></li> <% } else { %> <li><a href="/">Log in</a></li> <li><a href="/signup" class="btn">Sign up</a></li> <% } %> </ul> </nav> |
Logout Users
Now lastly when user presses the logout
button we will clear out the jwt
token from the cookie and delete the cookie and redirect the user to the login
page as shown below
controllers/authController.js
1 2 3 4 |
module.exports.logout_get = (req, res) => { res.cookie('jwt', '', { maxAge: 1 }); res.redirect('/'); } |
BUY FULL SOURCE CODE