Backend Notes
Backend Notes
● Understand Package.json
● Both files work together to ensure smooth development for you and your
team.
● Let’s understand First the Functions, Like Different ways to write functions
● Write a username into a Txt file with the help of the ‘fs’ system
● Console.log ( ‘module’ )
● → It gives the result of all modules we can do with that file in the nodeJs
● Module.exports.age = 5;
● module.exports.addNumber = function(a,b){}
● Npm Package - lodash
● npm i lodash
● Widely used library
● Lots of functions which helps deal with data.
DAY 3
● Server in Nodejs
● Imagine you're sending a message to your friend, and you want to include
information like your name, age, and a list of your favorite hobbies.
● You can't just send the message as is,
● you need to organize the information in a way that both you and your friend
understand.
● JSON is a bit like this organized format for exchanging data between
computers.
● JSON is a lightweight
● Structured and organized Data because
● in most contexts, JSON is represented as a string
{
"name": "Alice",
"age": 25,
"hobbies": ["reading", "painting", "hiking"]
}
● Inter Conversion JSON to an Object in Node.js:
—---------------------------------------------------------------
● Create a server
● Port Number?
● Let’s suppose in a building – 100 rooms are there, for someone to reach he
must know the room number right?
● Methods to share data
● So there are lots of methods out there to send or receive data according to
their needs.
● GET
● POST
● PATCH
● DELETE
● GET
Similarly, the GET method is used to request data from the server.
app.listen(3000, ()=>{
console.log('listening on port 3000');
})
DAY 4
● Database
● This is all Data we must have to store to run a fully functional restaurant
● So we have to deal with data
● Now There are lots of Database out there in the market, we can use
according to our need
○ SQL
○ PostgreSQL
○ MongoDB
○ MariaDB
○ Oracle
● Databases typically have their own server systems to manage and provide
access to the data they store.
● These database server systems are separate from Node.js servers but
work together to create dynamic and data-driven web applications
● Node.js server is responsible for handling HTTP requests from clients (like
web browsers) and returning responses.
● It processes these requests, communicates with the database server, and
sends data to clients.
● Setup MongoDB
Ans) NO
—> Setup MongoDB locally is quite tough for most of you. But relax we are
here to help you
For MacOS
https://stackoverflow.com/questions/65357744/how-to-install-mongodb-on-apple-
m1-chip
For Windows
https://www.geeksforgeeks.org/how-to-install-mongodb-on-windows/
—- Trust me Give some time to it until you will download the MongoDB in your
system. There is no point to move ahead without installing MongoDB
● MongoDB Syntax and Queries
In SQL:
use mydb;
In SQL:
In MongoDB:
db.createCollection("users");
3. Insert Data:
In MongoDB:
4. Query Data:
In SQL:
SELECT * FROM users WHERE age > 21;
In MongoDB:
5. Update Data:
In SQL:
In MongoDB:
6. Delete Data:
In SQL:
In MongoDB:
● There are lots of Tools in the market that help to visualize data like
mongoDB compass, MongoDB Robo 3T
● mongodb://127.0.0.1:27017
{
"name": "Alice",
"age": 28,
"work": "Chef",
"mobile": "123-456-7890",
"email": "[email protected]",
"address": "123 Main St, City",
"salary": 60000
}
{
"name": "Mango Smoothie",
"price": 4.99,
"taste": "Sweet",
"is_drink": true,
"ingredients": ["mango", "yogurt", "honey"],
"num_sales": 45
}
{
"name": "Spicy Chicken Wings",
"price": 9.99,
"taste": "Spicy",
"is_drink": false,
"ingredients": ["chicken wings", "spices", "sauce"],
"num_sales": 62
}
● MongoDB speaks its own language (protocol) to interact with the database
server.
● Node.js communicates in JavaScript.
● The driver translates the JavaScript code from Node.js into a format that
MongoDB can understand and vice versa.
● The driver provides a set of functions and methods that make it easier to
perform common database operations from your Node.js code.
● The driver helps you handle errors that might occur during database
interactions. It provides error codes, descriptions, and other details to help
you troubleshoot issues.
● The most popular driver is the official MongoDB Node.js driver, also known
as the mongodb package.
npm install mongodb
● Mongoose
● With Mongoose, you can define how your data should look, like making a
blueprint for your documents. It's like saying, "In our database, each
person's information will have a name, age, and email." This makes sure
your data stays organized.
● Mongoose helps you make sure the data you put into the database is
correct. It's like having someone check if you've written your email address
correctly before sending a message.
● Very easy to query from the database
● Database Connection
1. Import Mongoose and Define the MongoDB URL: In the db.js file, you
first import the Mongoose library and define the URL to your MongoDB
database. This URL typically follows the format
mongodb://<hostname>:<port>/<databaseName>. In your code,
you've set the URL to 'mongodb://localhost:27017/mydatabase',
where mydatabase is the name of your MongoDB database.
2. Set Up the MongoDB Connection: Next, you call mongoose.connect()
to establish a connection to the MongoDB database using the URL and
some configuration options (useNewUrlParser, useUnifiedTopology,
etc.). This step initializes the connection process but does not actually
connect at this point.
3. Access the Default Connection Object: Mongoose maintains a default
connection object representing the MongoDB connection. You retrieve this
object using mongoose.connection, and you've stored it in the variable
db. This object is what you'll use to handle events and interact with the
database.
4. Define Event Listeners: You define event listeners for the database
connection using methods like .on('connected', ...),
.on('error', ...), and .on('disconnected', ...). These event
listeners allow you to react to different states of the database connection.
5. Start Listening for Events: The code is set up to listen for events. When
you call mongoose.connect(), Mongoose starts the connection process.
If the connection is successful, the 'connected' event is triggered, and
you log a message indicating that you're connected to MongoDB. If there's
an error during the connection process, the 'error' event is triggered,
and you log an error message. Similarly, the 'disconnected' event can
be useful for handling situations where the connection is lost.
6. Export the Database Connection: Finally, you export the db object, which
represents the MongoDB connection, so that you can import and use it in
other parts of your Node.js application.
To sum it up, the db.js file acts as a central module that manages the
connection to your MongoDB database using Mongoose. It sets up the
connection, handles connection events, and exports the connection object so
that your Express.js server (or other parts of your application) can use it to
interact with the database. When your server runs, it typically requires or
imports this db.js file to establish the database connection before
handling HTTP requests.
{
"name": "Alice",
"age": 28,
"work": "Chef",
"mobile": "123-456-7890",
"email": "[email protected]",
"address": "123 Main St, City",
"salary": 60000
}
https://mongoosejs.com/docs/guide.html
● Parameters:
● Type, required, unique, etc
● What is body-parser
● When a client (e.g., a web browser or a mobile app) sends data to a server,
it typically includes that data in the body of an HTTP request.
● This data can be in various formats, such as JSON, form data, or
URL-encoded data. bodyParser helps parse and extract this data from
the request so that you can work with it in your Express.js application.
● bodyParser processes the request body before it reaches your route
handlers, making the parsed data available in the req.body for further
processing.
● bodyParser.json() automatically parses the JSON data from the
request body and converts it into a JavaScript object, which is then stored
in the req.body
● we need an Endpoint where the client sends data and data needs to be
saved in the database
● we need a method called POST
● Now code the POST method to add the person
● If we send the random values as well Mongoose will not save random
values other than predefined schema
● Async and await are features in JavaScript that make it easier to work with
asynchronous code, such as network requests, file system operations, or
database queries.
● Using try-and-catch block
● The try block contains the code for creating a new Person document and
saving it to the database using await newPerson.save().
● If an error occurs during any step, it is caught in the catch block, and an
error response is sent with a 500 Internal Server Error status.
app.post('/person', async (req, res) => {
try {
const newPersonData = req.body;
const newPerson = new Person(newPersonData);
● CRUD application
● In any application at the core level, we are always handling the database
● Now Let’s suppose the client wants data on all the persons
● So we need an endpoint for that /person
module.exports = MenuItem;
DAY 6
● We are now creating a POST method to save menu details and it’s similar
to person details and the same for the GET method
https://drive.google.com/file/d/1TswAyCgfsa04Hp6f4OP-Umg_GVkdW4eQ/view?
usp=sharing
● Now if someone told you to give a list of people who are only waiters
● Then we can create an endpoint like this
● /person/chef
● /person/waiter
● /person/manager
● But this is not the correct method to create as many functions Here we can
use parametrized endpoints
● It can be dynamically inserted into the URL when making a request to the
API.
● localhost:3000/person/:work
module.exports = router;
● Now in server.js, we will use this personRoutes
// Import the router files
const personRoutes = require('./routes/personRoutes');
● Update Operation
● We will update our person Records, and for that, we will create an endpoint
from where we are able to update the record
● For Updation, we need two things
○ Which record we want to update?
○ What exactly do we want to update?
● For update, we will use the PUT method to create an endpoint
● What is a unique identifier in a document in a collection?
● It’s _id which Mongodb itself gives, We will use this to find the particular
record that we want to update
● —> And now we will send the data the same as we did in the POST
method.
if (!updatedPerson) {
return res.status(404).json({ error: 'Person not found'
});
}
● Delete Operation
● We will Delete our person Records, and for that we will create an endpoint
from where we are able to delete the record
● For Deletion, we need one thing
○ Which record we want to update?
● For deletion, we will use the DELETE method to create an endpoint
● What is a unique identifier in a document in a collection?
● It’s _id which Mongodb itself gives, We will use this to find the particular
record that we want to delete
if (!deletedPerson) {
return res.status(404).json({ error: 'Person not found' });
}
● It is a tool that keeps a record of every version of your code, so you can
always go back to a previous state if something goes wrong.
● Install Git: If you haven't already, download and install Git on your
computer. You can get it from the official Git website:
https://git-scm.com/downloads
● If you want to work with git in your project →
● Run git init inside the root folder of your project
● This command tells Git to start tracking changes in your project folder.
git status
● After making changes to your project (e.g., writing code), you'll want to save
those changes in Git.
git add .
● The . means "add all changes." You can replace it with specific file names
if needed.
● gitignore
# Other entries...
● If you want to collaborate with others or back up your code online, you can
create a remote repository on platforms like GitHub
● Pull Changes
● If you're collaborating with others, you can fetch their changes and merge
them into your code using git pull.
● Host MongoDB database
● MongoDB Atlas provides a Free cluster for users where you can host your
database for free.
● MongoDB Atlas offers a cloud-based platform for hosting MongoDB
databases
● The free tier allows developers to explore and experiment with the database
without incurring any costs.
● https://www.mongodb.com/atlas/database
● Dotenv
● In your server file (usually the main entry point of your application), require
and configure the dotenv module.
require('dotenv').config();
● Remember to keep your .env file secure and never commit it to a public
version control system like Git, as it may contain sensitive information.
Typically, you should include the .env file in your project's .gitignore file
to prevent accidental commits.
● Now we can test the MongoDB Cluster and check whether our data is
present or not in the online DB
● Now we are going to host our server so that our Application or Endpoints is
accessible to all the users over the Internet.
● We are using localhost and our endpoints are only accessible within our
computer
● We have to make it publicly available, so there are lots of company who
helps us to make our application run 24*7
● Like, AWS, Google Cloud, etc. but these charge too much amount for our
application
● So we are going to use some free services to host our nodeJS application,
which lots of company provides for developer purposes.
● Like, Heroku, Netlify, Render, etc
DAY 8
● Middleware
Imagine you're at a restaurant, and you've placed an order for your favorite dish. Now,
before that dish reaches your table, it goes through several stages in the kitchen. Each
stage involves different tasks, like chopping vegetables, cooking, and adding spices.
Middleware is a bit like these stages in the kitchen—it's something that happens in
between your request and the final response in a web application.
Now, let's apply this idea to a web application, like the "Node Hotel" system:
In the context of Node.js, imagine you want to log every request made to your "Node
Hotel" application. You could use middleware for this.
// Middleware Function
const logRequest = (req, res, next) => {
console.log(`[${new Date().toLocaleString()}] Request made to:
${req.originalUrl}`);
next(); // Move on to the next phase
};
// Using Middleware in Express
const express = require('express');
const app = express();
// Apply Middleware to all Routes
app.use(logRequest);
// Define Routes
app.get('/', (req, res) => {
res.send('Welcome to Node Hotel!');
});
app.get('/menu', (req, res) => {
res.send('Our delicious menu is coming right up!');
});
// Start the Server
const PORT = 3000;
app.listen(PORT, () => {
console.log(`Server is running on http://localhost:${PORT}`);
});
In this example, logRequest is our middleware. It logs the time and the requested
URL for every incoming request. The app.use(logRequest) line tells Express to
use this middleware for all routes.
So, when you access any route (like / or /menu), the middleware runs first, logs the
request, and then the route-specific code executes.
In summary, middleware is like a series of tasks that happen behind the scenes in a
web application. It's a way to add extra functionality to your application's
request-response cycle, such as logging, authentication checks, or modifying
request data, before it reaches its final destination.
In Express.js, the next() function is a callback that signals to Express that the current
middleware function has completed its processing and that it's time to move on to the
next middleware function or route handler in the chain.
● Authentication & Authorization
Tag me on Linkedin for Notes – show Demo How you can post
Imagine you're the manager of the "Node Hotel" application, and you want to ensure
that only authorized staff members can access certain features. This is where
authentication comes in.
● Scenario: When a staff member, let's say a chef, wants to log in to the Node
Hotel system, they need to prove that they are indeed the chef they claim to be.
● In Practice: In Node.js, authentication involves checking the chef's credentials,
like a username and password, to make sure they match what's on record. It's
like asking the chef to enter a secret code (password) and confirming that it's
correct.
Now, let's add a layer of authorization based on the roles of the staff members.
● Scenario: Once the chef has proven their identity, you, as the manager, want to
control what they can and cannot do. For instance, chefs should be able to
update the menu items, but maybe not manage staff salaries.
● In Practice: In Node.js, after authenticating the chef, you'll use authorization to
decide what parts of the system they have access to. It's like giving the chef a
key card (authorization) that lets them into the kitchen but not into the manager's
office.
Implementation in Node.js:
● Authentication: When Chef John logs in, the system checks if the provided
username and password match what's on record for Chef John.
● Authorization: Once authenticated, Chef John is authorized to modify menu
items but may not have permission to change other critical settings.
In simple terms, authentication in Node.js for your hotel application ensures that each
staff member is who they say they are, and authorization determines what they're
allowed to do once their identity is confirmed.
It's like having a secure system where only the right people get access to the right
areas of your hotel management application.
1. Authentication:
○ The first step is to verify the identity of the user or system entity attempting
to access a resource or perform an action. This involves checking
credentials such as usernames and passwords or using other
authentication methods like tokens, API keys, or certificates.
2. Authorization:
○ Once the identity is verified through authentication, the system moves on to
authorization. Authorization determines what actions or resources the
authenticated user or entity is allowed to access based on their
permissions, roles, or other access control mechanisms.
The reason for this order is straightforward: before you can determine what someone is
allowed to do (authorization), you need to know who they are (authentication).
Authentication establishes the identity, and authorization defines the permissions
associated with that identity.
In the context of web applications, middleware for authentication is typically applied
first in the request-response cycle to verify the user's identity. If authentication is
successful, the request proceeds to authorization middleware to determine what the
authenticated user is allowed to do.
It's important to note that while authentication and authorization are often discussed as
distinct steps, they work together as essential components of a security strategy to
control access to resources and protect against unauthorized actions.
● Passport.js
Think of Passport.js as a helpful tool that makes it easier for developers to handle user
authentication in their Node.js applications. It simplifies the process of authenticating
users by providing a set of pre-built strategies for different authentication methods,
such as username and password, social media logins (like Facebook or Google), and
more.
1. Middleware: In the context of web development, middleware is software that sits
between the application and the server. Passport.js acts as middleware,
intercepting requests and adding authentication-related functionality to them.
2. Strategy: Passport.js uses the concept of strategies for handling different
authentication methods. A strategy is a way of authenticating users. Passport.js
comes with various built-in strategies, and you can also create custom strategies
to support specific authentication providers.
3. Serialize and Deserialize: Passport.js provides methods for serializing and
deserializing user data. Serialization is the process of converting user data into a
format that can be stored, usually as a unique identifier. Deserialization is the
reverse process of converting that unique identifier back into user data. These
processes are essential for managing user sessions.
● Install Passport
To use Passport.js in a Node.js application, you need to install the passport package
along with the authentication strategies you intend to use.
For this course, we are using Local strategies authentication (username and
password).
Once you've installed these packages, you can set up and configure Passport.js in
your application.
passport.use(new LocalStrategy(
async (username, password, done) => {
// Your authentication logic here
}
));
● In the Local Strategy's verification function, you typically query your database to
find the user with the provided username. You then compare the provided
password with the stored password.
● In the context of LocalStrategy, Passport.js expects the verification function
to have the following signature:
function(username, password, done)
● The done callback should always be the last parameter, and it's essential to
maintain this order for Passport.js to work correctly. If you change the order of
parameters, you risk breaking the expected behavior of Passport.js.
● Once you have configured Passport Local Strategy, the next steps typically
involve integrating it into your application.
● In route, we should use passport.authenticate() to initiate the
authentication process.
● To authenticate any routes, we need to pass this as an middleware
app.use(passport.initialize());
app.get('/', passport.authenticate('local', { session: false }), function (req, res) {
res.send('Welcome to our Hotel');
})
app.use(passport.initialize());
const localAuthMiddleware = passport.authenticate('local', { session: false });
app.get('/', localAuthMiddleware, function (req, res) {
res.send('Welcome to our Hotel');
})
● Now, we can test the ‘ / ‘routes it needs parameter
● Now, rather than all the passport codes in a server file. We can separate it into
another file name auth.js
● And in the server.js file, we will import the passport
// sets up Passport with a local authentication strategy, using a Person model
for user data. - Auth.js file
const passport = require('passport');
const LocalStrategy = require('passport-local').Strategy;
const Person = require('./models/Person'); // Adjust the path as needed
passport.use(new LocalStrategy(async (username, password, done) => {
try {
console.log('Received credentials:', username, password);
const user = await Person.findOne({ username });
if (!user)
return done(null, false, { message: 'Incorrect username.' });
const isPasswordMatch = user.password === password ? true : false;
if (isPasswordMatch)
return done(null, user);
else
return done(null, false, { message: 'Incorrect password.' })
} catch (error) {
return done(error);
}
}));
module.exports = passport; // Export configured passport
● Store Plain Password
● Storing plain passwords is not a secure practice. To enhance security, it's highly
recommended to hash and salt passwords before storing them.
● You can use the bcrypt library for password hashing in your Node.js
application.
● Now we have to update our person model to store hashed passwords. Modify the
registration logic to hash the password before saving it to the database.
● Because the end user didn’t know about hashing, we have to internally maintain
it. Like we are saving the hashed password before saving it into the database
● We are using a Mongoose middleware hook to perform an action before saving a
document to the database. Specifically, it's using the pre middleware to execute
a function before the save operation.
personSchema.pre('save', async function(next) {
const person = this;
// Hash the password only if it has been modified (or is new)
if (!person.isModified('password')) return next();
try {
// Generate a salt
const salt = await bcrypt.genSalt(10);
// Hash the password with the salt
const hashedPassword = await bcrypt.hash(person.password, salt);
// Override the plain password with the hashed one
person.password = hashedPassword;
next();
} catch (error) {
return next(error);
}
});
This line is a conditional check that prevents unnecessary rehashing of the password
when the document is being saved.
When you use bcrypt to hash a password, the library internally stores the salt as part
of the resulting hashed password. This means that you don't need to separately store
the salt in your database; it is included in the hashed password itself.
When you hash a password using bcrypt.hash, the library generates a random salt,
hashes the password along with the salt, and produces a hashed password that
incorporates both the salt and the hashed value.
The hashedPassword now contains both the hashed password and the salt.
● Modify Auth code
We have to also modify the password-matching logic in the passport auth file.
● Compare function
When you later want to verify a user's entered password during login, you use
bcrypt.compare. This function internally extracts the salt from the stored hashed
password and uses it to hash the entered password for comparison.
Sessions or Tokens
Sessions are a way to maintain user state and authenticate users in web applications.
1. User Authentication
When you visit a website or use a web application, you must log in to access certain
features or personalized content. Sessions or tokens are used to authenticate users,
proving that they are who they claim to be. This ensures that only authorized users can
access restricted areas or perform certain actions.
Web applications often need to remember user information as they navigate through
different pages or interact with the app. Sessions or tokens help maintain this user
state. For example, if you add items to your shopping cart on an e-commerce website,
the website needs to remember those items as you browse other pages. Sessions or
tokens store this information so that it can be accessed later.
3. Security
Sessions and tokens play a crucial role in securing web applications. They help
prevent unauthorized access by verifying the identity of users before granting them
access to sensitive data or functionality. Additionally, they can be used to protect
against common security threats such as session hijacking or cross-site request
forgery (CSRF) attacks.
5. Scalability
Sessions and tokens are designed to scale with the size and complexity of web
applications. They provide a flexible and efficient way to manage user authentication
and state, even as the number of users or requests increases. This scalability is
essential for ensuring that web applications can handle growing traffic and user
demands without sacrificing performance.
In summary, sessions and tokens are essential components of web development,
enabling user authentication, maintaining state, ensuring security, personalizing
experiences, and supporting scalability. They form the foundation of secure and
user-friendly web applications that can provide personalized and seamless
experiences to users.
● A session is a way or a small file, most likely in JSON format, that stores
information about the user, such as a unique ID, time of login expirations, and so
on. It is generated and stored on the server so that the server can keep track of
the user requests.
Working
● Creation: When you visit a website for the first time, the website may send a
small text file (the cookie) to your browser.
● Storage: Your browser stores the cookie on your computer or device. Each
cookie is associated with a specific website and contains information such as a
unique identifier and any data the website wants to remember about you.
● Sending with Requests: When you revisit the website or navigate to different
pages on the same site, your browser automatically includes the cookie in the
HTTP requests it sends to the website's server.
● Server Processing: The website's server receives the cookie along with the
request. It can then read the cookie to retrieve the stored information about you.
● Usage: Websites use cookies for various purposes, such as remembering your
login status, storing your preferences, tracking your activities for analytics
purposes, and personalizing your browsing experience.
Types of Cookies
● Session Cookies: These cookies are temporary and are deleted when you close
your browser. They are often used for maintaining your login state during a
browsing session.
● Persistent Cookies: These cookies are stored on your device for a specified
duration, even after you close your browser. They can be used for purposes such
as remembering your preferences or login information across multiple visits to a
website.
Privacy and Security
Cookies can raise privacy concerns because they can be used to track users' browsing
behavior across different websites. However, cookies cannot execute code or transmit
viruses, and they can only store information that the website itself provides.
In summary, cookies are small text files stored on your computer by websites you
visit. They help websites remember information about you and enhance your browsing
experience by personalizing content, maintaining login status, and tracking
preferences. While cookies are an essential part of web functionality, they also raise
privacy considerations, and users can manage their cookie settings in their web
browsers.
It's not mandatory that the cookies received from the server will be stored in the
"Cookies" storage of your browser. The browser provides multiple storage options,
each serving different purposes and offering various capabilities:
1. Cookies Storage: Cookies received from the server are typically stored in the
"Cookies" storage of your browser. These cookies can include session cookies,
which are deleted when you close your browser, and persistent cookies, which
are stored for a longer period.
2. Local Storage: Local storage is a mechanism that allows web applications to
store data locally in the browser. Unlike cookies, data stored in local storage is
not automatically sent to the server with every request. This storage option is
often used for caching data, storing user preferences, or implementing client-side
features.
3. Session Storage: Session storage is similar to local storage but is scoped to a
particular browsing session. Data stored in session storage is cleared when you
close the browser or tab. It's commonly used for temporary data storage or for
maintaining a state within a single browsing session.
Important Points
● While cookies are commonly used for storing session identifiers ( session IDs) or
authentication tokens received from the server, web applications can choose to
store this information in local storage or session storage instead.
● The choice of storage mechanism depends on factors such as security
requirements, application architecture, and use case. Cookies offer automatic
inclusion in HTTP requests and can be more secure if configured properly, but
local storage and session storage provide more control over data management
on the client side.
● While cookies are a common way to store data received from the server, web
applications have the flexibility to choose other storage options such as local
storage or session storage based on their requirements.
● Working
Note- Those are not authentication files, they are authorization ones. While
receiving a token, the server does not look up who the user is, it simply authorizes the
user’s requests relying on the validity of the token.
Difference between Session & Token
Criteria Token-based
Session authentication method authentication method
2 What the user sends to the server A cookie The token itself
to have their requests authorized
3 What does the server do to Looking up in its databases to find Decrypting the user’s token
authorize users’ requests the right session thanks to the ID and verifying its signature
the user sends with a cookie
4 Can the server admins perform Yes, because the session is stored No, because the token is
securities operations like logging on the server stored on the user’s
users out, changing their details, machine
etc
How Session works
How Token works
DAY 10
● Definition: JWT is a specific type of token format defined by the JSON Web
Token standard (RFC 7519). It is a compact and self-contained means of
transmitting information between parties as a JSON object.
● Structure: JWTs consist of three parts: header, payload, and signature. They are
typically encoded and signed using cryptographic algorithms.
● Usage: JWTs are commonly used for authentication and authorization in web
applications and APIs. They can store user claims, such as user ID, roles,
permissions, and custom data, in a secure and portable format.
● Statelessness: JWTs are stateless, meaning the server does not need to store
session information. This makes them suitable for distributed architectures and
scalable systems.
JWT Structure
A JWT is composed of three sections separated by dots (.), following the format
header.payload.signature.
1. Header: Contains metadata about the type of token and the cryptographic
algorithms used to secure it. It typically consists of two parts:
○ Typ (Type): Specifies the type of token, usually set to "JWT".
○ Alg (Algorithm): Indicates the cryptographic algorithm used to sign the
token, such as HMAC SHA256 or RSA.
2. Payload: Contains the claims or statements about the subject (user) and any
additional data. It consists of a set of claims that represent assertions about the
user, such as their identity, roles, or permissions. Claims are categorized into
three types:
○ Reserved Claims: Predefined claims standardized by the JWT
specification, such as iss (issuer), sub (subject), aud (audience), exp
(expiration time), and iat (issued at).
○ Public Claims: Custom claims defined by the application developer to
convey information about the user.
○ Private Claims: Custom claims agreed upon by parties that exchange
JWTs, not registered or standardized.
3. Signature: Verifies the integrity of the token and ensures that it has not been
tampered with during transmission. It's created by taking the encoded header,
encoded payload, a secret (for HMAC algorithms), and applying the specified
algorithm to generate the signature.
Authentication Flow
JWT Functions
jwt.sign():
● This function is used to generate a new JWT token based on the provided
payload and options.
● It takes three parameters:
○ payload: This is the data you want to include in the token. It can be any
JSON object containing user information, metadata, or any other relevant
data.
○ secretOrPrivateKey: This is the secret key used to sign the token. It
can be a string or a buffer containing a secret cryptographic key.
○ options (optional): These are additional options that control the behavior
of the token generation process, such as expiration time (expiresIn),
algorithm (algorithm), and more.
jwt.verify():
● This function is used to verify and decode a JWT token to retrieve the original
payload.
● It takes three parameters:
○ token: The JWT token to be verified.
○ secretOrPublicKey: The secret key or public key used to verify the
token's signature. If the token was signed using a symmetric algorithm
(e.g., HMAC), you need to provide the same secret key used to sign the
token. If it was signed using an asymmetric algorithm (e.g., RSA), you need
to provide the public key corresponding to the private key used for signing.
○ options (optional): Additional options for verification, such as algorithms
(algorithms), audience (audience), issuer (issuer), and more.
// Verify and decode the JWT token
jwt.verify(token, secretKey, (err, decoded) => {
if (err) {
// Token verification failed
console.error('Token verification failed:', err.message);
} else {
// Token verification successful
console.log('Decoded token:', decoded);
}
});
1. Signup Route (/signup): This route will handle user registration and issue a
JWT token upon successful registration.
2. Login Route (/login): This route will handle user login and issue a new JWT
token upon successful authentication.
3. Protected Routes: These routes will be accessed only by providing a valid JWT
token.
Install JWT
First, you'll need to install the necessary packages for working with JWT. In Node.js,
you can use packages like jsonwebtoken to generate and verify JWTs.
Create a JWT Auth Middleware function, which is responsible for authentication via
Tokens
// jwtAuthMiddleware.js
const jwt = require('jsonwebtoken');
const jwtAuthMiddleware = (req, res, next) => {
// Extract the JWT token from the request header
const token = req.headers.authorization.split(' ')[1];
if (!token) return res.status(401).json({ error: 'Unauthorized' });
try {
// Verify the JWT token
const decoded = jwt.verify(token, process.env.JWT_SECRET);
// Attach user information to the request object
req.user = decoded;
next();
} catch (err) {
console.error(err);
res.status(401).json({ error: 'Invalid token' });
}
};
module.exports = jwtAuthMiddleware;
// Login route
router.post('/login', async (req, res) => {
try {
// Extract username and password from request body
const { username, password } = req.body;
// Find the user by username
const user = await Person.findOne({ username });
// If user does not exist or password does not match, return error
if (!user || !(await user.comparePassword(password))) {
return res.status(401).json({ error: 'Invalid username or
password' });
}
const payload = { id: user.id, email: user.email }
// Generate JWT token
const token = generateToken(payload);
// Send token in response
res.json({ token });
} catch (err) {
console.error(err);
res.status(500).json({ error: 'Internal Server Error' });
}
});
Profile Route
When the server receives this request, it parses the Authorization header to
extract the JWT token.
The split(' ') method separates the header value into an array of substrings using
the space (' ') character as the delimiter. The [1] index accesses the second element
of this array, which is the JWT token.
Problems
You run a movie theater, and you want to offer discounts based on a person's age. Write a
JavaScript program that asks the user for their age and then displays a message:
- If the age is less than 18, display "You get a 20% discount!"
- If the age is between 18 and 65 (inclusive), display "Normal ticket price applies."
- If the age is 65 or older, display "You get a 30% senior discount!"
Create a JavaScript program to calculate the area of a rectangle. Ask the user for the length
and width of the rectangle and store them in variables. Calculate and display the area using
the formula: `area = length * width`.
You're creating an online store. Define a JavaScript object named "product" with the following
properties:
- name (string)
- price (number)
- inStock (boolean)
Create at least three products using your object template and display their details using
console.log.
Problem 4: Arrays
You're organizing a party and want to keep track of the guest list. Create an array called
"guestList" and add the names of at least five guests. Then, write a program that checks if a
given name is on the guest list. If the name is found, display "Welcome to the party, [name]!";
otherwise, display "Sorry, you're not on the guest list."
Problem 5: JSON (JavaScript Object Notation)
You're working on a weather app. Create a JSON object representing the weather forecast for
a specific day. Include properties like "date," "temperature," "conditions," and "humidity."
Display the information using console.log.
Remember to encourage your students to experiment and think creatively while solving these
problems. They can use the concepts you've taught them to come up with their own solutions.
This will not only help solidify their understanding but also foster their problem-solving skills in
JavaScript.
Solution
const product1 = {
name: "Smartphone",
price: 399.99,
inStock: true
};
const product2 = {
name: "Laptop",
price: 999.99,
inStock: false
};
const product3 = {
name: "Headphones",
price: 49.99,
inStock: true
};
console.log(product1);
console.log(product2);
console.log(product3);
Problem 4: Arrays
const weatherForecast = {
date: "2023-08-06",
temperature: 28,
conditions: "Sunny",
humidity: 60
};
DAY - 02
Problems
You're starting a new project and want to manage your project's dependencies using NPM.
Explain the purpose of NPM and how it helps in managing packages. Create a simple
package.json file for your project, specifying the name, version, and a few dependencies of
your choice.
Write a JavaScript function named calculateCircleArea that takes the radius of a circle
as a parameter and returns the area of the circle. You can use the formula area = π *
radius^2. Test the function with a few different radii.
Problem 3: Callback Functions
Create a function named performOperation that takes two numbers and a callback
function as parameters. The callback function should determine the operation to be performed
(addition, subtraction, multiplication, or division) on the two numbers. Call the
performOperation function with different numbers and callback functions for each
mathematical operation.
Write a Node.js program that uses the fs module to read the contents of a text file named
"notes.txt" and display them in the console.
Create a Node.js program that uses the os module to display the following system
information:
Use the lodash library to solve the following problem: Given an array of numbers, write a
function that returns the sum of all even numbers in the array. Use the _.sumBy function from
lodash to achieve this.
Solution
Problem 1: NPM and Package.json
NPM (Node Package Manager) is a tool that helps you manage libraries and packages in your Node.js
projects. It allows you to easily install, update, and remove packages that you need for your project.
To create a package.json file for your project, you can use the following example:
{
"name": "my-project",
"version": "1.0.0",
"dependencies": {
"lodash": "^4.17.21"
}
}
function calculateCircleArea(radius) {
return Math.PI * radius ** 2;
}
function add(x, y) {
return x + y;
}
function subtract(x, y) {
return x - y;
}
function multiply(x, y) {
return x * y;
}
function divide(x, y) {
return x / y;
}
const fs = require('fs');
const os = require('os');
const _ = require('lodash');
function sumOfEvenNumbers(numbers) {
const evenNumbers = _.filter(numbers, num => num % 2 === 0);
return _.sumBy(evenNumbers);
}
Problems
Explain in your own words what a server is in the context of Node.js. Then, write step-by-step instructions on
how to create a basic server using Express.js.
b) Given a JSON data string: {"name": "Alice", "age": 25, "hobbies": ["reading",
"painting"]}, explain how you would extract the value of the "age" key.
c) How would you convert the following object into a JSON data string? {"title": "Book", "pages":
200}
a) Explain what the HTTP GET method is used for in the context of web development.
b) Write the code to create a simple Express.js route that responds with "Hello, World!" when a user visits the
root URL ("/").
Problem 5: JSON Parsing and Object Conversion
a) Given a JSON data string: {"product": "Laptop", "price": 999.99}, explain how you would
parse it into a JavaScript object.
b) You have an object: { "name": "Bob", "age": 30 }. How would you convert it into a JSON data
string?
Imagine you're building an API for a weather app. Your API needs an endpoint to retrieve the current weather.
Create an Express.js route that responds with a JSON object containing the current temperature, conditions,
and city.
Solution
● A server in Node.js is a computer program that receives and responds to requests from clients (like
web browsers or mobile apps) over a network. It processes requests and sends back appropriate
responses.
● To create a basic server using Express.js:
app.listen(3000, () => {
console.log('Server is running on port 3000');
});
Problem 2: JSON Manipulation
a) JSON (JavaScript Object Notation) is a lightweight data interchange format used to exchange data between
a server and a client. It's easy for humans to read and write, and it's easy for machines to parse and generate.
b) To extract the value of the "age" key from the JSON data:
a) An API (Application Programming Interface) is a set of rules and protocols that allows different software
components to communicate and interact with each other. It defines how requests and responses should be
structured.
b) An endpoint is a specific URL (Uniform Resource Locator) that represents a particular function or service
provided by an API. It's the specific location where clients can make requests to access certain data or perform
actions.
c) Example of an endpoint in a social media app: /users/{username} to retrieve user information based on
their username.
a) The HTTP GET method is used to request data from a server. It's often used to retrieve information or
resources from a specified URL.
app.listen(3000, () => {
console.log('Server is running on port 3000');
});
DAY - 04
Problems
Question 1: Difference Between MongoDB Server & Node.js Server
Explain the difference between a MongoDB server and a Node.js server in terms of their roles and
functionalities. Provide examples of situations where you would use each server type.
a) Write a MongoDB query to create a new document in a collection named "students" with fields "name,"
"age," and "grade."
b) Write a MongoDB query to update the "age" field of a document in the "employees" collection with the name
"John" to 30.
c) Write a MongoDB query to delete a document from the "products" collection with the name "Product A."
d) Write a MongoDB query to retrieve all documents from the "orders" collection where the total amount is
greater than $100.
Explain the main differences between SQL databases and MongoDB in terms of data structure, querying
language, and use cases. Provide examples of scenarios where you might choose one over the other.
Compare and contrast the following MongoDB and SQL queries for retrieving data:
Answer: The MongoDB server is responsible for storing and managing data in the MongoDB database. It
handles data storage, retrieval, and manipulation operations. On the other hand, a Node.js server is a runtime
environment that executes JavaScript code. It handles incoming requests from clients, processes them, and
can interact with databases like MongoDB to retrieve or update data. You would use a MongoDB server to
store and manage data, while a Node.js server is used to handle application logic and serve client requests.
a) Answer:
b) Answer:
c) Answer:
d) Answer:
Answer: SQL databases use structured tables with rows and columns to store data, while MongoDB uses
flexible and dynamic documents in collections. SQL databases use SQL as a querying language, while
MongoDB uses a JavaScript-like syntax for queries. SQL databases are suitable for applications with
well-defined and structured data, such as financial systems. MongoDB is better for projects with changing or
unstructured data, like content management systems or real-time analytics.
Question 4: Query Comparison
c) Answer: Both queries calculate the total amount of orders grouped by status.
DAY - 05
Problems
Create a POST method API to store data or menu items as per the schema we discussed ( /menu )
Create a GET method API to List down the All Menu Items as per the schema we discussed ( /menu )
You're building a simple task management application. Your task is to create a POST API endpoint for adding
new tasks to the database. Assume you've already set up an Express application and connected it to your
MongoDB using Mongoose.
a) Design the Mongoose schema for a "Task" with fields for "title," "description," "priority," and "dueDate."
b) Create a POST API endpoint /api/tasks that allow clients to submit new tasks to the database. Ensure it
handles request validation and responds with the newly created task.
Continuing with the task management application, you need to create a GET API endpoint for retrieving a list of
tasks from the database.
Create a GET API endpoint /api/tasks that retrieve a list of all tasks from the database. Ensure it handles
errors and responds with the list of tasks in JSON format.
Solution
Answer 1: POST method API to store data or menu items as per the schema we discussed on /menu
Answer 2: GET method API to List down the All Menu Items as per the schema we discussed on /menu
a) Design the Mongoose schema for a "Task" with fields for "title," "description," "priority," and "dueDate."
module.exports = Task;
b) Create a POST API endpoint /api/tasks that allow clients to submit new tasks to the database. Ensure it
handles request validation and responds to the newly created task.
a) Create a GET API endpoint /api/tasks that retrieve a list of all tasks from the database
Problems
Question 1: Create a parameterized GET Method API for the Menu Item on the Basis of
taste Type via using Express Router
( /menu/:taste )
Question 2: Create a PUT Method API to update the MenuItem Records ( menu/:id )
Question 3: Create a DELETE Method API to delete the MenuItem Records ( menu/:id )
Solution
if (!response) {
return res.status(404).json({ error: 'Menu Item not found' });
}
console.log('data updated');
res.status(200).json(response);
}catch(err){
console.log(err);
res.status(500).json({error: 'Internal Server Error'});
}
})