0% found this document useful (0 votes)
6 views122 pages

Unit-3 Back End (Autosaved)

Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PPTX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
6 views122 pages

Unit-3 Back End (Autosaved)

Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PPTX, PDF, TXT or read online on Scribd
You are on page 1/ 122

Basic Authentication

It is a process of identifying user identity.


User Authentication contains various steps, check out this flowchart to
know more. We will be using this flow to build the authentication system in
our application.
Packages Required
You will be needing these following 'npm' packages.
1.express

2.express-validator
It's a server-side data validation library. So, even if a malicious user bypasses the
client-side verification,
the server-side data validation will catch it and throw an error.
3.body-parser
It is nodejs middleware for parsing the body data.
4.bcryptjs
This library will be used to hash the password and then store it to database.
5.jsonwebtoken
jsonwebtoken will be used to encrypt our data payload on registration and return
a token.
6.mongoose
Mongoose is a MongoDB object modeling tool designed to work in an asynchronous
environment.
Initiate Project

 We will start by creating a node project. So, Create a new folder with the
name 'node-auth' and follow the steps below. All the project files should be
inside the 'node-auth' folder.
 npm init
 npm init will ask you some basic information about project. Now, you have
created the node project, it's time to install the required packages. So, go
ahead and install the packages by running the below command.
npm install express express-validator body-parser bcryptjs jsonwebtoken
mongoose --save
Now, create a file index.js and add this code.

 // File : index.js
 const express = require("express");
 const bodyParser = require("body-parser");
 const app = express();
 // PORT
 const PORT = process.env.PORT || 4000;
 app.get("/", (req, res) => {
 res.json({ message: "API Working" });
 });
 app.listen(PORT, (req, res) => {
 console.log(`Server Started at PORT ${PORT}`);
 });
• If you type node index.js in the terminal, the server will start at PORT
4000.

• You have successfully set up your NodeJS app application. It's time to set
up the database to add more functionality.
Setup MongoDB Database db.js in config folder

 const mongoose=require("mongoose");
 constmongoDB_Url=process.env.MONGODB_URL;
 mongoose.connect('mongodb://127.0.0.1:27017/authors');
 mongoose.connection.on('error',err=>{
 console.log(err);
 });
 mongoose.connection.on('connected',res=>{
 console.log('connected');
 });
• Now, we are done the database connection. Let's create
the User Model to save our registered users.
• Go ahead and create a new folder named model. Inside
the model folder, create a new file User.js.
• We will be using mongoose to create UserSchema.
User.js in model folder
 const mongoose = require("mongoose");
const UserSchema = mongoose.Schema({
 username: {
 type: String,
 required: true
 },
 email: {
 type: String,
 required: true
 },
 password: {
 type: String,
 required: true
 },
 createdAt: {
 type: Date,
 default: Date.now()
 }
 });

// export model user with UserSchema
 module.exports = mongoose.model("user", UserSchema);
Now, we are done with Database Connection, User Schema. So, let's go
ahead and update our index.js to connect our API to the database.
const express = require("express");
const bodyParser = require("body-parser");
const InitiateMongoServer = require("./config/db");
// Initiate Mongo Server
InitiateMongoServer();
const app = express();
const PORT = process.env.PORT || 4000;
// Middleware
app.use(bodyParser.json());

app.get("/", (req, res) => {


res.json({ message: "API Working" });
});
app.listen(PORT, (req, res) => {
console.log(`Server Started at PORT ${PORT}`);
});
You have successfully connected your app to the MongoDB server.
Now, the next thing we have to do is make a /user/signup route to register a
new user. We will see this in the next section.
UserSignup
The Route for user registration will be '/user/signup'.
Create a folder named routes. In the 'routes' folder,
create a file named user.js
routes/user.js
 // Filename : user.js

 const express = require("express");


 const { check, validationResult} = require("express-validator/check");
 const bcrypt = require("bcryptjs");
 const jwt = require("jsonwebtoken");
 const router = express.Router();

 const User = require("../model/User");

 /**
 * @method - POST
 * @param - /signup
 * @description - User SignUp
 */
• router.post(
• "/signup",
• [
• check("username", "Please Enter a Valid Username")
• .not()
• .isEmpty(),
• check("email", "Please enter a valid email").isEmail(),
• check("password", "Please enter a valid password").isLength({
• min: 6
• })
• ],
• async (req, res) => {
• const errors = validationResult(req);
• if (!errors.isEmpty()) {
• return res.status(400).json({
• errors: errors.array()
• });
• const {
• username,
• email,
• password
• } = req.body;
• try {
• let user = await User.findOne({
• email
• });
• if (user) {
• return res.status(400).json({
• msg: "User Already Exists"
• });
• }
• user = new User({
• username,
• email,
• password
• });

• const salt = await bcrypt.genSalt(10);


• user.password = await bcrypt.hash(password, salt);

• await user.save();
• const payload = {
• user: {
• id: user.id
• }
• };
• jwt.sign(
• payload,
• "randomString", {
• expiresIn: 10000
• },
• (err, token) => {
• if (err) throw err;
• res.status(200).json({
• token
• });
• }
• );
• } catch (err) {
• console.log(err.message);
• res.status(500).send("Error in Saving");
• }
• }
• );
• Now, we have created the user registration in 'routes/user.js'.
So, we need to import this in index.js to make it work.
• So, the updated index file code should look like this.
• index.js
• const express = require("express");
• const bodyParser = require("body-parser");
• const user = require("./routes/user"); //new addition
• const InitiateMongoServer = require("./config/db");
• // Initiate Mongo Server
• InitiateMongoServer();
• const app = express();
• const PORT = process.env.PORT || 4000;
• app.use(bodyParser.json());

• app.get("/", (req, res) => {


• res.json({ message: "API Working" });
• });
• app.use("/user", user);
• app.listen(PORT, (req, res) => {
• console.log(`Server Started at PORT ${PORT}`);
Let's start the user registration using postman. A
postman is a tool for API testing.
User Login

Now, it's time to implement the Login router which will be mounted on
'/user/login'.
Here is the code snippet for login functionality. Add the below code snippet in
user.js
• router.post(
• "/login",
• [
• check("email", "Please enter a valid email").isEmail(),
• check("password", "Please enter a valid password").isLength({
• min: 6
• })
• ],
• async (req, res) => {
• const errors = validationResult(req);
• if (!errors.isEmpty()) {
• return res.status(400).json({
• errors: errors.array()
• });
• }
• const { email, password } = req.body;
• try {
• let user = await User.findOne({
• email
• });
• if (!user)
• return res.status(400).json({
• message: "User Not Exist"
• const isMatch = await bcrypt.compare(password, user.password);
• if (!isMatch)
• return res.status(400).json({
• message: "Incorrect Password !"
• });
• const payload = {
• user: {
• id: user.id
• }
• };
• jwt.sign(
• payload,
• "randomString",
• {
• expiresIn: 3600
• },
• (err, token) => {
• if (err) throw err;
• res.status(200).json({
• token
• });
• }
• );
• } catch (e) {
• console.error(e);
• res.status(500).json({
• message: "Server Error"
• });
• }
Get LoggedIn User

 Now, your User Signup and User Login is working, and you are getting a token in
return.

 So, our next task will be to Retrieve the LoggedIn user using the token. Let's go and
add this functionality.

 The /user/me route will return your user if you pass the token in the header. In the
file route.js, add the below code snippet.
• /**
• * @method - GET
• * @description - Get LoggedIn User
• * @param - /user/me
• */

• router.get("/me", auth, async (req, res) => {


• try {
• // request.user is getting fetched from Middleware after token authentication
• const user = await User.findById(req.user.id);
• res.json(user);
• } catch (e) {
• res.send({ message: "Error in Fetching user" });
• }
• As you can see, we added the auth middleware as a parameter in
the /user/me GET route, so let's define auth function.

• Go ahead and create a new folder named middleware. Inside this


folder, create a file named auth.js

• This auth middleware will be used to verify the token, retrieve


user based on the token payload.

• middleware/auth.js
middleware/auth.js
 const jwt = require("jsonwebtoken");
 module.exports = function(req, res, next) {
 const token = req.header("token");
 if (!token) return res.status(401).json({ message: "Auth Error" });
 try {
 const decoded = jwt.verify(token, "randomString");
 req.user = decoded.user;
 next();
 } catch (e) {
 console.error(e);
 res.status(500).send({ message: "Invalid Token" });
 }
How to Test the application?

 PostMan is required for Testing the API. If you don't have PostMan
installed first, install it.
 First, register the user or login if you are already registered.
 From step 1, you will get a token. Copy that token and put in the header.
 Hit Submit
 Here is a preview of testing.
Some of Postman's top benefits include:
• Easy to create, share, test, and document APIs.
• Store information for running tests in different environments.
• Store data for use in other tests.
• Integrates with build systems.
• Easy to move tests and environments to code repositories.
• Good UI.
JSON web token | JWT

A JSON web token(JWT) is JSON Object which is used to securely transfer information
over the web(between two parties). It can be used for an authentication system and can also
be used for information exchange. The token is mainly composed of header, payload,
signature. These three parts are separated by dots(.). JWT defines the structure of
information we are sending from one party to the another, and it comes in two forms –
Serialized, Deserialized. The Serialized approach is mainly used to transfer the data through
the network with each request and response. While the deserialized approach is used to read
and write data to the web token.
Deserialized Header
 A header in a JWT is mostly used to describe the cryptographic
operations applied to the JWT like signing/decryption technique used
on it. It can also contain the data about the media/content type of the
information we are sending. This information is present as a JSON
object then this JSON object is encoded to BASE64URL. The
cryptographic operations in the header define whether the JWT is
signed/unsigned or encrypted and are so then what algorithm
techniques to use. A simple header of a JWT looks like the code
below:

 {
 "typ":"JWT",
 "alg":"HS256"
 Payload
The payload is the part of the JWT where all the user data is actually added. This data is also
referred to as the ‘claims’ of the JWT. This information is readable by anyone so it is always
advised to not put any confidential information in here. This part generally contains user
information. This information is present as a JSON object then this JSON object is encoded
to BASE64URL. We can put as many claims as we want inside a payload, though unlike
header, no claims are mandatory in a payload. The JWT with the payload will look
something like this:
 {
 "userId":"b07f85be-45da",
 "iss": "https://provider.domain.com/",iss (issuer), exp (expiration time), sub
 (subject), and aud (audience).
"sub": "auth/some-hash-here",
 "exp": 153452683
 }
Serialized Signature

 JWT in the serialized form represents a string of the following format:

 [header].[payload].[signature]
 allthese three components make up the serialized JWT. We already
know what header and payload are and what they are used for.Let’s
talk about signature.
Signature

 This is the third part of JWT and used to verify the authenticity of token. BASE64URL encoded header and
payload are joined together with dot(.) and it is then hashed using the hashing algorithm defined in a header
with a secret key. This signature is then appended to header and payload using dot(.) which forms our actual
token header.payload.signature

 Syntax :

 HASHINGALGO( base64UrlEncode(header) + “.” + base64UrlEncode(payload),secret)


 header:
 { JWT Example :
 "alg" : "HS256",
 "typ" : "JWT"
 }
 Payload:
 {
 "id" : 123456789,
 "name" : "Joseph"
 }
 Secret: RajanSaluja
 JSON Web Token

 eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6MTIzNDU2Nzg5LCJuYW1lIjoiSm9zZXBoIn0.OpOSSw
7e485LOP5PrzScxHb7SR6sAOMRckfFwi4rp7o
JWT Tokens

Use Cases:
1. Authentication: JWTs are often used for user authentication. When a user logs in, a JWT is issued,
which is then used to identify the user in subsequent requests.
2. Information Exchange: JWTs can be used to securely exchange information between parties, such as
in single sign-on (SSO) systems, where user identity is passed between different services or domains.
Benefits:
3. Stateless: JWTs are stateless, meaning the server doesn't need to keep track of token states. This
makes them scalable and suitable for microservices architectures.
4. Compact: JWTs are compact and can be easily transmitted as URL parameters or in the headers of
HTTP requests.
5. Self-Contained: JWTs carry information (claims) within the token itself, eliminating the need to query a
database or validate the token against the issuer.
JWT Tokens
 Security Considerations:
• Data Integrity: JWTs are signed, ensuring the data's integrity. However,
they do not provide confidentiality, so sensitive information should not
be stored in them without proper encryption.
• Expiration: JWTs should have short lifetimes, and proper refresh
mechanisms should be in place to minimize the risk of token theft or
unauthorized access.
• Signature Key Management: The security of JWTs relies on the
management of the signing key. If the key is compromised, the entire
system is at risk.
OAuth Tokens

Use Cases:
1. Authorization: OAuth tokens are primarily used for authorization. They grant access to resources or
actions on behalf of a user, without sharing the user's credentials.
2. Third-Party Access: OAuth is designed for scenarios where third-party applications or services need
controlled access to a user's resources (e.g., social media logins or API access).
Benefits:
3. Granular Access Control: OAuth allows fine-grained control over what resources a client (third-party
app) can access, based on scopes and permissions.
4. Revocable Access: OAuth tokens can be revoked, which is important for managing access to user data
when a user decides to de-authorize an application.
5. User Consent: OAuth includes a user consent step, where the user explicitly grants or denies access to
their data.
• Security Considerations:
• Token Leakage: OAuth tokens are sensitive and should be
protected from theft or leakage. This can be done through secure
storage and transmission.
• Token Expiration: Proper token expiration and refresh
mechanisms are essential to mitigate the risk of long-lived tokens
being compromised.
• OAuth Version and Implementation: The security of OAuth
largely depends on the specific version and the implementation.
Careful consideration and best practices are needed.
Difference between JWT and Oauth

• Use Case: JWT is more for authentication and information exchange, while OAuth is
specifically designed for authorization and access delegation.
• Data Storage: JWTs store claims within the token, while OAuth tokens often reference data
stored on the authorization server.
• Authorization vs. Authentication: OAuth is primarily about authorization, while JWT can be
used for user authentication.
• Token Lifetime: OAuth tokens typically have shorter lifetimes and can be refreshed, while
JWTs can have longer lifetimes but should be used with refresh tokens for security.
• Revocation: OAuth tokens can be revoked, whereas JWTs are typically valid until they expire.
• User Consent: OAuth includes a user consent step, which is not a standard feature of JWT-
based authentication.
• Security: Both JWT and OAuth tokens require proper security measures, but the specific risks
and considerations differ.
Basic Authentication in Node.js using HTTP Header
 Authentication of the client is the first step before starting any Application. The basic
authentication in the Node.js application can be done with the help express.js framework.
Express.js framework is mainly used in Node.js application because of its help in handling
and routing different types of requests and responses made by the client using different
Middleware.

 HTTP WWW-Authenticate header is a response-type header and it serves as a support for


various authentication mechanisms which are important to control access to pages and other
resources as well.
Explanation of the Authentication:

Example
const express = require("express"); Index.js
 const fs = require("fs");
 const path = require('path');
const app = express();
 function authentication(req, res, next) {
 const authheader = req.headers.authorization;
 console.log(req.headers);
 if (!authheader) {
 let err = new Error('You are not authenticated!');
 res.setHeader('WWW-Authenticate', 'Basic');
 err.status = 401;
 return next(err)
 }
• const auth = new Buffer.from(authheader.split(' ')[1],
• 'base64').toString().split(':');
• const user = auth[0];
• const pass = auth[1];
• if (user == 'admin' && pass == 'password') {
• // If Authorized user
• next();
• } else {
• let err = new Error('You are not authenticated!');
• res.setHeader('WWW-Authenticate', 'Basic');
• err.status = 401;
• return next(err);
• }
• }
• // First step is the authentication of the client
• app.use(authentication)
• app.use(express.static(path.join(__dirname, 'public')));
• // Server setup
• app.listen((3000), () => {
• console.log("Server is Running ");
Disadvantages of Basic HTTP authentication

Eavesdropping: Without encryption, anyone with access to the


network traffic can intercept and read the credentials as they are
transmitted over the internet. This is known as a "man-in-the-middle"
attack. Attackers can use tools like packet sniffers to capture plaintext
usernames and passwords.
Password Theft: Since the credentials are transmitted in plaintext,
an attacker can easily capture them and use them for malicious
purposes, such as gaining unauthorized access to the user's account.
This can lead to unauthorized data access, identity theft, and more.
Brute Force Attacks: Attackers can capture the plaintext credentials
and attempt to crack the passwords using brute force or dictionary
attacks. Once they have the password, they can gain unauthorized
access to the user's account.
Credential Replay Attacks: An attacker may capture the
credentials and reuse them later to impersonate the legitimate
user. This can lead to unauthorized access and misuse of the
user's account.
Exposure of Sensitive Information: In addition to usernames
and passwords, other sensitive information may also be
transmitted in plaintext if the application does not enforce
encryption. This could include session tokens or other
authentication-related data.
Lack of Data Integrity: Without encryption, there is no
guarantee that the data has not been tampered with during
transmission. Attackers could modify the data to gain
unauthorized access or disrupt the communication.
Compliance Issues: In many regions and industries, transmitting
sensitive information, especially user credentials, without
encryption can violate data protection regulations and compliance
standards. This can lead to legal consequences and fines.
Cookies

• Cookies are small files which are stored on a user’s computer.


• They are used to hold a modest amount of data specific to a particular
client and website and can be accessed either by the web server or by
the client computer
• When cookies were invented, they were basically little documents
containing information about you and your preferences. For instance,
when you select your language in which you want to view your
website, the website would save the information in a document called
a cookie on your computer, and the next time when you visit the
website, it would be able to read a cookie saved earlier. That way the
website could remember your language and let you view the website
in your preferred language without having to select the language
again.
Cookies

A cookie can contain any type of information


such as the time when you visited the website,
the items that you added into your shopping
basket, all the links you clicked in website, etc.,

If a cookie is created in a particular website, and


you visit another website later, the latter would
not be able to read the contents from the first
website, in other words only the same website
that saves information to a cookie can access it.
Types of internet Cookies
 Session Cookies: A session cookie only lasts for the
duration of users using the website. A web browser
normally deletes session cookies when it quits.
 Persistent Cookies: A persistent cookie outlast user
sessions. If a persistent cookie has its maximum age 1
year, then within a year, the initial value set in the cookie
would be sent back to the server every time the user
visits the server. Example: Gmail.
 Third-party cookies: Third party cookies are the
cookies being set with the different domain than the one
shown in the address bar. For example, if you were to
visit Sendflowers.com, it may set the cookie for the
address of SomeAdvertiser.com. Later, when you visit
RebuidEngines.com it may set the cookie for
SomeAdvertiser.com. Both of these cookies will be used
by SomeAdvertiser.com to ascertain that you are a
HTTP Cookies in Node.js
 Users can follow the syntax below to set and get the cookies using NodeJS.

 app.get("/", (req, res) => {


 res.cookie("name", value);
 });

 app.get("/", (req, res) => {


 res.send(req.cookies);
 });
npm i express cookie-
parser
Example 1

 In the example, we have created the basic server using express. Also,
we have used the ‘cookieParser’ in the express app.

 We show the welcome message whenever users go on the home


route after running the application. Also, we have created the car
object containing some properties.

 Whenever the user goes to the ‘setcookies’ route, it sets the car data
in the cookies. Users can go to the ‘getcookies’ route to access all
cookies. Users can go on the ‘clear’ route to clear the cookies.
Example 1
 let express = require("express");
 let cookieParser = require("cookie-parser");
 //setup express app
 let app = express();

 app.use(cookieParser());

 //basic route for homepage


 app.get("/", (req, res) => {
 res.send("Express app is created successfully, and you are on homepage");
 });

 // create a JSON object to store car data


 let car = {
 name: "BMW",
 model: "X5",
 price: 50000,
 };
Example 1
 // route to set car object as cookie
 app.get("/setcar", (req, res) => {
 res.cookie("carData", car);
 res.send("car data is stored in cookies");
 });
 // route to get car object from cookies
 app.get("/getcar", (req, res) => {
 res.send(req.cookies);
 });
 // route to clear car object from cookies
 app.get("/clear", (req, res) => {
 res.clearCookie("carData");
 res.send("Cookies are cleared!");
 });
 app.listen(8000, (err) => {
 if (err) throw err;
 console.log("listening on port 8000");
Example 2

 In the example, we set the cookies with the expiry time. We


have created the table and homeWindow object containing
the various properties in the key-value pair.
 We can set both objects with different expiry times by
making a get request on the ‘setCookies’ route. Also, users
can access and delete particular cookies by passing the name
as a parameter. In the output, users can observe that we
accessed only table objects.
Example 2
 let express = require("express");
 let cookieParser = require("cookie-parser");
 //setup express app
 let app = express();
 app.use(cookieParser());
 //basic route for homepage
 app.get("/", (req, res) => {
 res.send("Express app is created successfully, and you are on homepage");
 });
 let table = {
 color: "brown",
 material: "wood",
 size: "small",
 price: 100,
 };
 let homeWindow = {
 color: "white",
 material: "glass",
 size: "big",
 price: 200,

Example 2

 // set cookies for table and homeWindow with different expiry time
 app.get("/setCookies", (req, res) => {
 res.cookie("table", table, { maxAge: 900000, httpOnly: true });
 res.cookie("homeWindow", homeWindow, { maxAge: 600000, httpOnly: true });
 res.send("Cookies are set with different expiry time");
 });

 // get cookies
 app.get("/getCookies", (req, res) => {
 res.send(req.cookies);
 });
 // get cookies with specific name
 app.get("/getCookies/:name", (req, res) => {
 res.send(req.cookies[req.params.name]);
 });
 // delete cookies with specific name
 app.get("/deleteCookies/:name", (req, res) => {
 res.clearCookie(req.params.name);
 res.send("Cookies with name " + req.params.name + " is deleted");
 });
 //server listens to port 3000
 app.listen(8000, (err) => {
 if (err) throw err;
 console.log("listening on port 8000");
Advantages of Cookies in web applications
• Session Management: Cookies are commonly used to manage user sessions.
When a user logs in to a website, a session cookie is often created. This
cookie contains a unique identifier that allows the server to associate
subsequent requests with that user's session. This is crucial for maintaining
user authentication and enabling personalized experiences during a single
visit to the site.
• User Authentication: Cookies are essential for user authentication. They
store information that verifies a user's identity, such as a user ID or a token.
When a user logs in, a cookie is set to maintain their authenticated state, and
subsequent requests are checked against this cookie to ensure the user is still
logged in.
• Personalization: Cookies are frequently used to personalize the user
experience. They can store user preferences, such as language settings, theme
choices, or product recommendations. When users return to the website, the
server can read these cookies and present a customized experience.
Advantages of Cookies in web applications
• Shopping Carts: In e-commerce applications, cookies are used to
maintain shopping cart contents. When users add items to their cart,
this information is stored in a cookie. This allows users to browse the
site, return later, and still see their selected items in the cart.
• Tracking and Analytics: Cookies are employed for tracking user
behavior and collecting analytics data. Tools like Google Analytics
use cookies to track user sessions, page views, and other interactions,
providing website owners with valuable insights for optimizing their
web applications.
• Remember Me Functionality: Many websites offer a "Remember
Me" option during login. When a user selects this option, a persistent
cookie is created that keeps them logged in across sessions. This is
convenient for users who want to avoid repeated logins.
Advantages of Cookies in web applications
• Security: Cookies can enhance security by preventing cross-
site request forgery (CSRF) attacks. Anti-CSRF tokens are
often stored in cookies to validate the authenticity of requests.
• Load Balancing: In cases of distributed web applications,
cookies can store information about the user's preferred server,
helping to evenly distribute the load among multiple servers.
• Tracking User Progress: In multi-step processes, such as
form submissions or online surveys, cookies can be used to
track the user's progress and allow them to resume from where
they left off.
• Ad Targeting: Cookies are also utilized by advertisers to track
user behavior and provide targeted advertisements. Ad
networks use cookies to identify users who have visited
specific sites and display ads that match their interests.
Disadvantages of Cookies
 Using cookies in web applications can introduce several security concerns. To
ensure the safety and privacy of users, it's essential to be aware of these issues and
implement mitigation strategies:

Data Theft (Session Hijacking): Attackers may attempt to


steal session cookies to impersonate a legitimate user. If
successful, they can gain unauthorized access to an account.
•Solution: Implement secure session management practices.
Use HTTPS to encrypt data in transit, employ HttpOnly and
Secure flags for cookies, and regenerate session IDs after
login to prevent session fixation attacks. Additionally, consider
implementing two-factor authentication (2FA) for sensitive
accounts.
Disadvantages of Cookies

Cross-Site Scripting (XSS): Malicious scripts injected into a web


page can access and steal cookies, potentially compromising user
accounts.
Solution: Input validation and output encoding are critical to
prevent XSS attacks. Implement Content Security Policy (CSP)
headers to restrict the sources of scripts that can run on a page.
Sanitize user-generated content and use security libraries to help
defend against XSS.
Cross-Site Request Forgery (CSRF): Attackers can trick users into
performing actions on a site without their consent, often exploiting the
user's authenticated session.
Solution: Use anti-CSRF tokens that are embedded in forms or in
cookies and are checked on form submissions. These tokens
Disadvantages of Cookies
Data Leakage and Privacy Concerns: Cookies can store sensitive user
information, which, if leaked, could violate privacy regulations.
Solution: Only store essential information in cookies. Use secure and
HttpOnly flags for cookies that contain sensitive data. Comply with
relevant data protection laws, such as GDPR, by obtaining user consent
for non-essential cookies and allowing users to manage their cookie
preferences.
Cookie Tampering: Attackers may try to manipulate the data stored in
cookies or create their own malicious cookies.
Solution: Sign cookies with a secret key or use a message
authentication code (MAC) to detect any alterations. This ensures the
integrity of the data stored in cookies. Also, implement server-side
validation of cookie data to prevent tampering.
Disadvantages of Cookies

Cookie Theft through Insecure Wi-Fi: When using public Wi-Fi, data in
cookies can be intercepted and stolen, compromising user accounts.
Solution: Encourage users to connect via secure networks whenever
possible. Use HTTPS to encrypt data in transit, and consider implementing
HTTP Strict Transport Security (HSTS) to ensure secure connections.
Persistent Cookies: Long-lived or persistent cookies can be a security risk if
they are stolen, as they remain valid for extended periods.
Solution: Limit the use of persistent cookies, especially for sensitive data.
Implement strict expiration policies for cookies and encourage users to log
out of their accounts when they're done to invalidate session cookies.
Disadvantages of Cookies

Third-Party Cookies: Third-party cookies, often used for advertising and


tracking, raise privacy concerns.
Solution: Comply with regulations like GDPR and CCPA by providing
clear information to users about third-party cookies, obtaining consent
where necessary, and allowing users to opt out of third-party tracking.
Denial of Service (DoS): Cookies can be manipulated to consume server
resources by sending a high volume of requests.
Solution: Implement rate limiting, request validation, and employ
Distributed Denial of Service (DDoS) protection mechanisms to
mitigate DoS attacks.
Limited Size of A Cookie for various browser

The maximum storage size for a single cookie in most web


browsers is approximately 4 KB (kilobytes). This limit is
defined in various web standards and is implemented by
browsers to prevent excessive data storage and potential
misuse of cookies. Keep in mind that this size limit is shared
among all cookies for a given domain. If you exceed this
limit, older cookies may be overwritten or discarded to make
room for new ones. It's important to be mindful of this
limitation when designing web applications that rely on
cookies for data storage.
Session Management using express-session Module in Node.js

Session management can be done in node.js by using the express-session


module. It helps in saving the data in the key-value form. In this module,
the session data is not saved in the cookie itself, just the session ID.

npm install express-session


const express = require("express")
const session = require('express-session')
const app = express()
// Port Number Setup
var PORT = process.env.port || 3000
// Session Setup
app.use(session({
// It holds the secret key for session
secret: 'Your_Secret_Key',
// Forces the session to be saved
// back to the session store
resave: true,
// Forces a session that is "uninitialized"
// to be saved to the store
saveUninitialized: true
}))
app.get("/", function(req, res){
// req.session.key = value
req.session.name = ‘Rajan’s Session'
return res.send("Session Set")
})
app.get("/session", function(req, res){
var name = req.session.name
return res.send(name)
/* To destroy session you can use
this function
req.session.destroy(function(error){
console.log("Session Destroyed")
})
*/
})
app.listen(PORT, function(error){
if(error) throw error
console.log("Server created Successfully on PORT :", PORT)
})
Express session middleware within a Node.js
application.

 const express = require('express');


 const session = require('express-session');
 const app = express();
 // Configure the session middleware
 app.use(session({
 secret: 'your-secret-key',
 resave: false,
 saveUninitialized: true,
 }));
 // Middleware to display the session data
 app.use((req, res, next) => {
 if (req.session.views) {
 req.session.views++;
 } else {
 req.session.views = 1;
 }
 res.send(`You've visited this page ${req.session.views} times.`);
 });

 app.listen(3000, () => {
 console.log('Server is running on port 3000');
 });
Express session middleware within a
Node.js application.
Express session middleware is an essential component in a Node.js
application, particularly when using the Express.js framework. It plays a
crucial role in handling and managing user sessions, which are a
fundamental aspect of web applications.
Session Management: The primary role of Express session middleware is
to manage user sessions. A session is a temporary and unique interaction
between a user and a web application. It allows the application to
recognize and remember a user as they navigate through the site without
requiring them to authenticate with each request. This is essential for
maintaining user state and providing a personalized experience.
 Data Storage: Express session middleware stores session data, such as
user authentication information or user-specific settings, on the server.
This ensures that sensitive user data isn't exposed on the client-side and
is protected from tampering or unauthorized access.
Express session middleware within a
Node.js application.
• Session ID: It generates and assigns a unique session
identifier, usually in the form of a session cookie, to each
client's browser. This session ID is used to link the client
to their session data stored on the server.
• Authentication: It is often used in conjunction with user
authentication mechanisms. For example, after a user logs
in, the session middleware can store a user's credentials or
user ID in the session data, making it easy to check if a
user is authenticated on subsequent requests.
• State Management: It helps in maintaining the state of a
user's interactions with the application. For instance, it
can store a user's shopping cart items, language
preferences, or any other relevant data that needs to
persist during their visit.
Express session middleware within a
Node.js application.
• Security: Express session middleware can be configured to
enhance the security of user sessions. It can prevent
common security issues like session fixation, session
hijacking, and session timeout management.
• Middleware Integration: It integrates seamlessly into the
Express.js middleware stack. This means it can be easily
added to your application, and you can configure it to work
with other middlewares, such as authentication middleware
or logging middleware.
• Customization: Express session middleware allows you to
configure session storage options, session expiration, and
other settings to tailor it to your specific application
Express.js route handler for creating user session
when a client connect
 const express = require('express');
 const session = require('express-session');
 const app = express();
 app.use(session({
 secret: 'your-secret-key', // Change this to a strong, random value in production
 resave: false,
 saveUninitialized: true,
 }));
 // Simulated user data (you would typically retrieve this from a database)
 const users = [
 { id: 1, username: 'user1', password: 'password1' },
 { id: 2, username: 'user2', password: 'password2' },
 // Middleware to parse JSON request bodies
 app.use(express.json());
 // Login route
 app.post('/login', (req, res) => {
 const { username, password } = req.body;
 // Simulated authentication logic (replace with your authentication mechanism)
 const user = users.find(u => u.username === username && u.password === password);
 if (user) {
 // Set session data when the user is authenticated
 req.session.user = user;
 res.status(200).send('Login successful');
 } else {
 res.status(401).send('Login failed');
 }
 });
 app.listen(3000, () => {
 console.log('Server is running on port 3000');
Difference between Cookies and Session

Cookies Session
Cookies are small text files
Sessions are used to store
used to store user
user information on the
information on the user’s
user’s server side.
computer.
A session ends when the user
Cookies expire after a
closes the browser or logs
specified lifetime or duration.
out.
Cookies can only store a
Sessions have a 128 MB size
limited amount of data of
to store data for one time.
4KB in a browser.
Cookies store information in a Session stores data in an
text file. encrypted format.
Testing

When testing with Node.js, you’ll typically use either Mocha, Chai, Jest, Chai HTTP, or Sinon.
Unit testing
Unit testing involves testing your application’s code and logic, which includes anything that your
application can do on its own without having to rely on external services or data.
Integration testing
Integration testing involves testing your application as it connects with services inside or outside of the
application.
Regression testing
Regression testing involves testing your application’s behavior after a set of changes have been made.
End-to-end testing
End-to-end testing involves testing the full end-to-end flow of your project, including external HTTP
calls and complete flows within your project.
Component testing
Component testing involves testing the totality of a service, including the modules and external
services connected to it. However, it’s expensive to perform because it takes a lot of time.
How to Test Node.js REST APIs Using Mocha, Chai, and
Chai-HTTP

 Mocha is a widely-used testing framework that is compatible


with various JavaScript frameworks. One of its key features is
a flexible test runner that simplifies the process of managing
and executing test cases effectively.
 It also supports various testing styles, including synchronous
and asynchronous testing, allowing for a wide range of testing
scenarios.
 On the other hand, Chai and Chai-HTTP are assertion
libraries that you can use in conjunction with Mocha. Chai
provides a wide range of expressive and readable assertion
interfaces such as should, expect, and assert. While, Chai-
HTTP, an extension of Chai, provides an interface specifically
designed for testing HTTP requests and asserting their
responses.
How to Test Node.js REST APIs Using Mocha,
Chai, and Chai-HTTP
 By using Mocha in conjunction with Chai and Chai-HTTP, you
can test APIs effectively. The testing workflow involves:
• Making HTTP requests to the specified API endpoints.
• Defining the expected responses.
• Validating the received data from the specified source, the HTTP
status codes, and more.
 You can also simulate API error test scenarios that may arise in
such situations and what actions should trigger in the event they
occur.
Advantages and Disadvantages of Node Js Applications in
Restaurants
Advantages:
 Real-time Updates: Node.js is known for its ability to handle real-time
applications. In a restaurant, customers expect fast updates on the
availability of food options and order statuses. Node.js can handle real-
time updates efficiently, making it suitable for handling multiple
concurrent connections.
 Scalability: Node.js is highly scalable and can handle a large number of
concurrent connections, making it well-suited for a busy cafe. As the cafe
grows, it's relatively easy to scale the system horizontally to accommodate
increased traffic.
 Speed: Node.js is built on the V8 JavaScript engine, which is highly
performant. It can process incoming requests quickly, reducing latency in
the order processing system.
Advantages and Disadvantages of Node Js
Applications in Restaurants
• Rich Ecosystem: Node.js has a rich ecosystem of packages and
libraries available through npm. You can find pre-built modules for
various functionalities, making development more efficient.
• Single Language: Using JavaScript for both the frontend and backend
can simplify development and streamline communication between
different parts of the system.
• Community Support: Node.js has a large and active community,
which means you can find plenty of resources, tutorials, and help when
facing challenges during development.
Advantages and Disadvantages of Node Js
Applications in Restaurants
 Drawbacks:
• Single-Threaded: Node.js is single-threaded and uses an event-driven,
non-blocking I/O model. While this can be an advantage for handling
many concurrent connections, it can also be a drawback if you have CPU-
bound tasks or require multi-threading for certain operations. You need to
be careful not to block the event loop with time-consuming operations.
• Learning Curve: If your development team is not already familiar with
JavaScript and Node.js, there might be a learning curve, which can slow
down the development process initially.
• Callback Hell: Without proper design and organization, Node.js code can
become difficult to read and maintain due to callback hell, where callback
functions are nested deeply. However, this can be mitigated by using
modern JavaScript features and design patterns.
Advantages and Disadvantages of Node Js
Applications in Restaurants
 Drawbacks:
• Relatively New: Node.js is a relatively new technology compared to some other backend
options. This may raise concerns about its stability and long-term support. However, Node.js has
gained wide adoption and has proven its reliability in many production systems.
• Security: Security is a critical concern for any system handling customer data and payments.
Node.js itself is secure, but the security of your system largely depends on how well you
implement and configure security measures, which can be complex.
 In summary, Node.js can be a suitable choice for implementing a node Js application system in a
restaurant , especially when real-time updates and scalability are important. However, careful
planning, design, and consideration of the potential drawbacks are essential to ensure a successful
implementation. Security and performance optimization should be a top priority when developing
such a system.
Passport in Node.js
 The Passport is a node package, or library which we can install in any
nodeJs project.
 The Passport provides the functionality for authentication in the app.
 it provides different encryption strategies to encrypt user information, such
as a password.
 Passport allows us to establish the authentication session for the users.
Suppose you must log in again whenever you close the browser. It is
time−consuming. Isn’t it? So, Passport allows us to establish a session for a
particular time by storing the cookies in the browser. Users don't need to log
in whenever a user visits the webpage within the particular session time set
by the developers.
 Example of Passport Use Index.js

const express = require('express');


const session = require('express-session');
const passport = require('passport');
const LocalStrategy = require('passport-local').Strategy;
const bodyParser = require('body-parser');
const bcrypt = require('bcrypt');
const app = express();
flash = require('express-flash')
 Example of Passport Use
app.use(
session({
resave: true,
saveUninitialized: true,
secret:"yash is a super star",
cookie: { secure: false, maxAge: 14400000 },
})
);
// Set up middleware
app.use(express.static('public'));
app.use(bodyParser.urlencoded({ extended: true }));
app.use(session({ secret: 'your-secret-key', resave: false, saveUninitialized: true }));
app.use(passport.initialize());
app.use(passport.session());
app.use(flash());
 Example of Passport Use
app.use(
session({
resave: true,
saveUninitialized: true,
secret:"yash is a super star",
cookie: { secure: false, maxAge: 14400000 },
})
);
// Set up middleware
app.use(express.static('public'));
app.use(bodyParser.urlencoded({ extended: true }));
app.use(session({ secret: 'your-secret-key', resave: false, saveUninitialized:
true }));
app.use(passport.initialize());
app.use(passport.session());
app.use(flash());
 Example of Passport Use
// Dummy user database (Replace with a real database)
const users = [];

// Passport local strategy for user login


passport.use(new LocalStrategy(
(username, password, done) => {
const user = users.find((u) => u.username === username);
if (!user) return done(null, false, { message: 'Incorrect username.' });
if (!bcrypt.compareSync(password, user.password)) return done(null,
false, { message: 'Incorrect password.' });
return done(null, user);
}
));
 // Serialize and deserialize user
 passport.serializeUser((user, done) => done(null, user.id));
 passport.deserializeUser((id, done) => {
 const user = users.find((u) => u.id === id);
 done(null, user);
 });
 // Set up EJS as the view engine
 app.set('view engine', 'ejs');
 // Routes
 app.get('/', (req, res) => {
 res.render('login', { message: req.flash('error') });
 });
 app.get('/register', (req, res) => {
 res.render('register');
 });
 app.post('/register', (req, res) => {
 const { username, password } = req.body;
 const hashedPassword = bcrypt.hashSync(password, 10);
 // Simulate database storage (replace with actual DB operations)
 users.push({ id: Date.now().toString(), username, password: hashedPassword });

res.redirect('/');
 });
 app.post('/login',
 passport.authenticate('local', {
 successRedirect: '/dashboard',
 failureRedirect: '/',
 failureFlash: true,
 })
 );
 app.get('/dashboard', (req, res) => {
 res.send('Welcome to the dashboard!');
 });

app.listen(4200, () => {
 console.log('Server is running on http://localhost:3000');
Register.html
 <html>
 <body>
 <h2>
 Enter email and password values, and press submit button for registration
 </h2>
 <!-- Make the post request on the /register route with email and password data -->
 <form action = "/register" method = "post">
 <input type = "email" name = "username" />
 <br />
 <input type = "password" name = "password" />
 <br />
 <button type = "submit" name = "button"> Submit </button>
 </form>
 </body>
Login.html
 <html>
 <body>
 <h2> Enter the credentials to log in to the app</h2>
 <!-- When the user presses the submit button, it makes a post request on the login route -->
 <form action ="/login" method = "post">
 <input type = "email" name = "username" />
 <br />
 <input type = "password" name = "password" />
 <br />
 <button type = "submit" name = "button"> Submit </button>
 </form>
 </body>
Advantages of passport
 If we use Passport, then:
• We don’t have to leave our passwords exposed. The whole encryption
and decryption procedure is done by Passport including the hashing and
encrypting of passwords.
• Passport allows us to create and maintain sessions. For example, when
you visit any social media website or mobile app, you do not have to log
in, again and again, each time you want to use Instagram or Facebook.
Rather, the information is saved, which means you don’t have to log in
each time you want to use the website. In technical words, a session has
been created, and it will be maintained for the next few days, or a few
weeks, or a few months.
• Passport also allows us to easily integrate authentication using Google,
Facebook, LinkedIn, and various other social networking services.
Packages needed for Passports
 For using passport, we have to install 4 npm packages,
namely “passport“, “passport-local“, “passport-local-
mongoose” and “express-session
 In the command line, write the following command to
install all the four packages:

 npm install passport passport-local passport-local-


mongoose express-session
Passport Use with MongoDB
 var express = require('express');
 var app = express();
 const mongoose = require("mongoose");
 /* Requiring body-parser package
 to fetch the data that is entered
 by the user in the HTML form.*/
 const bodyParser = require("body-parser");
 // Telling our Node app to include all these modules
 const session = require("express-session");
 const passport = require("passport");
 const passportLocalMongoose =
 require("passport-local-mongoose");
 // Allowing app to use body parser
 app.use(bodyParser.urlencoded({ extended: true }));
Passport Use with MongoDB
 app.use(session({
 secret: "long secret key",
 resave: false,
 saveUninitialized: false
 }));
 // Initializing Passport
 app.use(passport.initialize());

// Starting the session
 app.use(passport.session());
 // Connecting mongoose to our database
 mongoose.connect(
 'mongodb://127.0.0.1:27017/userDatabase', {
 useNewUrlParser: true,
 useUnifiedTopology: true
 });
Passport Use with MongoDB
 /* Creating the schema of user which now
 include only email and password for
 simplicity.*/
 const userSchema = new mongoose.Schema({
 email: String,
 password: String
 });
 /* Just after the creation of userSchema,
 we add passportLocalMongoose plugin
 to our Schema */
 userSchema.plugin(passportLocalMongoose);
 // Creating the User model
 const User = new mongoose.model("User", userSchema);
 /* After the creation of mongoose model,
 we have to write the following code */
 passport.use(User.createStrategy());
 // Serializing and deserializing
 passport.serializeUser(User.serializeUser());
 passport.deserializeUser(User.deserializeUser());
 // Handling get request on the home route
 app.get("/", function (req, res) {
 /* req.isAuthentcated() returns true or
 false depending upon whether a session is
 already running or not. */
 if (req.isAuthenticated()) {
 /* if request is already authenticated,
 i.e. user has already logged in and
 there is no need to login again or
 we can say, session is running.*/
 res.send(
 "You have already logged in. No need to login again");
 }
 else {
 // If the user is new and
 // no session is Running already
 res.sendFile(__dirname + "/index.html");
 }
 // Handling get request on login route
 app.get("/login", function (req, res) {
 if (req.isAuthenticated()) {
 /* If request is already authenticated,
 i.e. user has already logged in and
 there is no need to login again. */
 res.send(
 "You have already logged in. No need to login again");
 }
 else {
 /* if session has expired, then user
 need to login back again and
 we will send the Login.html */
 res.sendFile(__dirname + "/login.html");
 }
 /* Registering the user for the first time
 handling the post request on /register route.*/
 app.post("/register", function (req, res) {
 console.log(req.body);
 var email = req.body.username;
 var password = req.body.password;
 User.register({ username: email },
 req.body.password, function (err, user) {
 if (err) {
 console.log(err);
 }
 else {
 passport.authenticate("local")
 (req, res, function () {
 res.send("successfully saved!");
 })
 }
 })
 // Handling the post request on /login route
 app.post("/login", function (req, res) {
 console.log(req.body);
 const userToBeChecked = new User({
 username: req.body.username,
 password: req.body.password
 });
 // Checking if user if correct or not
 req.login(userToBeChecked, function (err) {
 if (err) {
 console.log(err);
 res.redirect("/login");
 }
 else {
 passport.authenticate("local")
 (req, res,function () {
 User.find({ email: req.user.username },
 function (err, docs) {
 if (err) {
 console.log(err);
 }
 //login is successful
 console.log("credentials are correct");
 res.send("login successful");
 }
 });
 });
 }
 })
 })

// Allowing app to listen on port 3000
 app.listen(4000, function () {
 console.log("server started successfully");
 })
Index.html
 <!DOCTYPE html>
 <html>

<head>
 <title>Page Title</title>
 </head>
<body>
 <h1>REGISTER</h1>
 <form class="" action="/register" method="post">
 <input type="email" name="username"
 placeholder="Name" value="">
 <input type="password" name="password"
 placeholder="Password" value="">
 <button type="submit" name="button">
 Submit
 </button>
 </form>
 </body>
Login.html

 <!DOCTYPE html>
 <html lang="en" dir="ltr">
 <head>
 <meta charset="utf-8">
 <title></title>
 </head>
 <body>
 <h1>LOGIN</h1>
 <form class="" action="/login" method="post">
 <input type="email" name="username"
 placeholder="Name" value="">
 <input type="password" name="password"
 placeholder="Password" value="">
 <button type="submit" name="button">
 Submit
 </button>
 </form>
 </body>

How to handle errors in node.js
Error handling is a mandatory step in application development. A
Node.js developer may work with both synchronous and asynchronous
functions simultaneously. Handling errors in asynchronous functions is
important because their behavior may vary, unlike synchronous
functions. While try-catch blocks are effective for synchronous
functions, asynchronous functions can be dealt with callbacks,
promises, and async-await. Try-catch is synchronous means that if an
asynchronous function throws an error in a synchronous try/catch
block, no error throws. Errors thrown in Node.js applications can be
handled in the following ways:

 Using try-catch block


 Using callbacks
 Using promises and promise callbacks
 Using async-await
Using try-catch block:
 function dosomething() {
 throw new Error(
 'a error is thrown from dosomething');
}
 function init() {
 try {
 dosomething();
 }
 catch (e) {
 console.log(e);
 }
 console.log(
 "After successful error handling");
}
 init();
 Output:
 Error: a error is thrown from dosomething
 at dosomething (/home/cg/root/6422736/main.js:4:11)
 at init (/home/cg/root/6422736/main.js:9:9)
 at Object. (/home/cg/root/6422736/main.js:17:1)
 at Module._compile (module.js:570:32)
 at Object.Module._extensions..js (module.js:579:10)
 at Module.load (module.js:487:32)
 at tryModuleLoad (module.js:446:12)
 at Function.Module._load (module.js:438:3)
 at Module.runMain (module.js:604:10)
 at run (bootstrap_node.js:389:7)
 After successful error handling
 Explanation: The init() function is called which in turn calls dosomething() function which throws
an error object. This error object is caught by the catch block of the init() method. If there is no
proper handling of the error the program will terminate. The catch block prints the call stack to
Using callbacks:

A callback is a function called at the completion of a


certain task. Callbacks are widely used in Node.js as it
prevents any blocking and allows other code to be run
in the meantime. The program does not wait for the
file reading to complete and proceeds to print
“Program Ended” while continuing to read the file. If
any error occurs like the file does not exist in the
system then the error is printed after “Program
Ended”, else the content of the file is outputted.
 const fs = require("fs");

 fs.readFile('foo.txt', function (err, data) {


 if (err) {
 console.error(err);
 }
 else {
 console.log(data.toString());
 }
 });

 console.log("Program Ended");
 Output:
 Program Ended
 [Error: ENOENT: no such file or directory,
 open 'C:\Users\User\Desktop\foo.txt'] {
 errno: -4058,
 code: 'ENOENT',
 syscall: 'open',
 path: 'C:\\Users\\User\\Desktop\\foo.txt'
 }
 Explanation: In this case, the file does not exist in the system hence the error is thrown. Using promises and promise
callbacks: Promises are an enhancement to Node.js callbacks. When defining the callback, the value which is returned is
called a “promise”. The key difference between a promise and a callback is the return value. There is no concept of a
return value in callbacks. The return value provides more control for defining the callback function. In order to use
promises, the promise module must be installed and imported into the application. The .then clause handles the output of
the promise. If an error occurs in any .then clause or if any of the promises above are rejects, it is passed to the immediate
.catch clause. In case of a promise is rejected, and there is no error handler then the program terminates.
 const Promise = require('promise');
 const MongoClient = require('mongodb').MongoClient;
 const url = 'mongodb://localhost/TestDB';
 MongoClient.connect(url)
 .then(function (err, db) {
 db.collection('Test').updateOne({
Output:
 "Name": "Joe"
 }, // In this case we assume the url is wrong
MongoError: failed to connect to server
 { [localhost:27017]
 $set: {// error message may vary
 "Name": "Beck"
 }
 });
 })
Using async-await:

 Async-await is a special syntax to work with promises in a


simpler way that is easy to understand. When we use
async/await, .then is replaced by await which handles the
waiting in the function. The error handling is done by
the .catch clause. Async-await can also be wrapped in a try-
catch block for error handling. In case no error handler exists
the program terminates due to an uncaught error.
 async function f() {
 let response = await fetch('http://xyzurl');
}
 // f() becomes a rejected promise
 f().catch(alert);

Output:

// the url is wrong //


TypeError: failed to fetch

Whether you're preparing for your first job interview or aiming to


upskill in this ever-evolving tech landscape, GeeksforGeeks Courses
are your key to success. We provide top-quality content at affordable
prices, all geared towards accelerating your growth in a time-bound
manner. Join the millions we've already empowered, and we're here
to do the same for you.
Mongoose Populate() Method
 In MongoDB, Population is the process of replacing the specified path
in the document of one collection with the actual document from the
other collection.
 Need of Population: Whenever in the schema of one collection we
provide a reference (in any field) to a document from any other
collection, we need a populate() method to fill the field with that
document.
 Example: In the following example, we have one userSchema and
another postSchema, in the postSchema we have one
field postedBy which references a document from the User model.
 const userSchema = new mongoose.Schema({
 username: String,
 email: String
 })
 const postSchema = new mongoose.Schema({
 title: String,
 postedBy: {
 type: mongoose.Schema.Types.ObjectId,
 ref: "User"
 }
 })
 const User = mongoose.model('User', userSchema);
 const Post = mongoose.model('Post', postSchema);
 module.exports = {
 Source, Destination, User, Post
 Initially we have two collections users and posts in our
database GFG. And each collection contains a single document.
Example 1: We will perform the query to find all
the posts without using populate() method.
 // Requiring module
 const mongoose = require('mongoose');
 // Connecting to database
 mongoose.connect('mongodb://localhost:27017/GFG',
 {
 useNewUrlParser: true,
 useUnifiedTopology: true,
 useFindAndModify: false
 });
 // Creating Schemas
 const userSchema = new mongoose.Schema({
 username: String,

 const postSchema = new mongoose.Schema({
 title: String,
 postedBy: {
 type: mongoose.Schema.Types.ObjectId,
 ref: "User"
 }
 })
 // Creating models from userSchema and postSchema
 const User = mongoose.model('User', userSchema);
 const Post = mongoose.model('Post', postSchema);
 // Query to find and show all the posts
 Post.find()
 .then(p => console.log(p))
 .catch(error => console.log(error));
 Output: In the output, we can see that we get only ObjectId (_id field of user
document) in postedBy field, and not the whole document.
Example 2: We will perform the query to find all
the posts using populate() method.

 To overcome the above problem, populate() method is used to replace the


user ObjectId field with the whole document consisting of all the user
data. For this we only have to replace the query part in the above code in
main.js file with:
 Post.find()
 .populate("postedBy")
 .then(p=>console.log(p))
 .catch(error=>console.log(error));
 Note: In the argument of the populate() method we pass the field we want
to populate with the user data.
Output: After using the populate method, we can see that in
the output we can get all the user data inside
the postedBy field of posts.

You might also like

pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy