Node.js Express Backend Curriculum

An interactive learning atlas by mindal.app

Launch Interactive Atlas

Generate a curriculum for backend development with Node.js and Express. The graph should be organized to cover building RESTful services, connecting to a database for persistence, and implementing user authentication.

This curriculum focuses on backend development using Node.js and Express, covering the creation of RESTful services, integration with various databases for persistence, and implementing robust user authentication. It emphasizes foundational concepts moving to advanced topics for building scalable and secure applications. Key aspects include API design, database CRUD operations, and secure authentication methods like JWT and Bcrypt.

Key Facts:

  • The curriculum starts with Node.js and Express fundamentals, including project setup, middleware, routing, and handling HTTP requests for backend services.
  • It covers designing and implementing RESTful APIs by mapping HTTP methods to CRUD operations and structuring API routes, along with error handling.
  • Database integration includes both NoSQL (MongoDB with Mongoose) and SQL databases (MySQL/PostgreSQL with Sequelize/Prisma) for data persistence.
  • User authentication and authorization are covered, detailing methods like JWT and session-based authentication, password hashing with Bcrypt, and role-based access control.
  • Security best practices such as Helmet, rate limiting, input sanitization, and environment variables are integral for production-grade backend applications.

Database Integration for Persistence

This module delves into connecting Node.js/Express applications to various databases for data persistence, covering both NoSQL (MongoDB with Mongoose) and SQL (MySQL/PostgreSQL with Sequelize/Prisma) options. It includes defining schemas/models and performing CRUD operations, along with considerations for choosing the appropriate database type.

Key Facts:

  • Database integration is essential for data persistence in backend applications, supporting both NoSQL and SQL database types.
  • For NoSQL databases like MongoDB, Mongoose (an ODM library) is commonly used with Express.js to define schemas and perform CRUD operations.
  • SQL databases such as MySQL and PostgreSQL are integrated using ORMs like Sequelize or Prisma, which abstract SQL queries and simplify database interactions.
  • Key tasks include setting up database connections, defining data models (schemas), running migrations for SQL databases, and implementing CRUD functionality.
  • Understanding the trade-offs between SQL and NoSQL databases based on data structure and application requirements is a critical skill.

CRUD Operations and Migrations

CRUD Operations and Migrations encompass the essential functionalities for interacting with and managing database data and schemas. CRUD operations (Create, Read, Update, Delete) handle data manipulation, while migrations manage schema evolution for SQL databases.

Key Facts:

  • Implementing CRUD functionality is crucial for data manipulation, covering Create, Read, Update, and Delete operations.
  • ORMs/ODMs significantly simplify CRUD operations by providing object-oriented interfaces.
  • For SQL databases, migrations are essential to manage changes to the database schema over time.
  • Sequelize and Prisma offer robust migration tools to synchronize database structures with application models.
  • Consistent CRUD implementation and proper migration management ensure data integrity and application evolution.

Database Connection and Schema Definition

Database Connection and Schema Definition involve establishing a link between the Node.js application and the chosen database, along with structuring the data. This includes setting up credentials, configuring connection options, and defining data models or schemas.

Key Facts:

  • Establishing a database connection involves specifying connection URLs, credentials, and configuration options.
  • Data models or schemas provide structured representations of the data to be stored, used by both ORMs and ODMs.
  • In Mongoose, schemas define document structures with field types and validation rules.
  • ORMs like Sequelize and Prisma use models to represent database tables with attributes and data types.
  • Proper connection setup and schema definition are foundational for reliable data persistence.

Mongoose

Mongoose is an Object Data Modeling (ODM) library for MongoDB within Node.js, providing a schema-based solution for application data. It facilitates defining schemas and performing CRUD operations in an object-oriented manner.

Key Facts:

  • Mongoose is an ODM library specifically for MongoDB, offering schema-based data modeling.
  • It defines the structure of documents within a collection using schemas, specifying field types, default values, and validation rules.
  • Mongoose provides built-in and custom validators to ensure data integrity before saving to the database.
  • It simplifies Create, Read, Update, and Delete (CRUD) operations using object-oriented concepts.
  • Setup involves installing `express` and `mongoose`, and configuring the MongoDB connection in a Node.js project.

NoSQL Databases

NoSQL Databases offer flexible schemas and are designed for horizontal scalability, making them suitable for handling large volumes of unstructured or semi-structured data and high traffic loads. MongoDB is a common example.

Key Facts:

  • NoSQL databases handle unstructured or semi-structured data, offering flexibility in schema design.
  • They are designed for flexibility and horizontal scalability, suitable for large volumes of data and high traffic loads.
  • NoSQL databases often provide better performance for write-heavy applications and real-time operations.
  • MongoDB is a prominent example of a NoSQL database.
  • Use cases include social media, IoT applications, and content management systems.

Prisma

Prisma is a modern ORM that provides a type-safe client, schema-based approach, and powerful features for interacting with various databases, including PostgreSQL. It focuses on developer experience, data modeling, and migrations.

Key Facts:

  • Prisma is a modern ORM offering a type-safe client and a schema-based approach for database interactions.
  • It utilizes a `schema.prisma` file to define data models, which represent database tables.
  • Prisma Migrate is used to create and apply database migrations, ensuring the Prisma schema aligns with the database schema.
  • The Prisma Client, generated from the schema, provides a type-safe and intuitive way to query the database.
  • Setup involves installing Prisma, initializing it to create the schema file, and configuring the database connection in a `.env` file.

Sequelize

Sequelize is a robust Object-Relational Mapper (ORM) for Node.js and TypeScript, designed to simplify interactions with SQL databases like MySQL and PostgreSQL. It abstracts SQL queries and provides model definitions, migrations, and CRUD functionalities.

Key Facts:

  • Sequelize is an ORM for Node.js and TypeScript, supporting multiple SQL dialects including PostgreSQL, MySQL, and SQLite.
  • It allows for model definitions that represent database tables, specifying attributes and data types.
  • Sequelize offers robust migration capabilities to manage changes to existing database schemas over time.
  • It simplifies CRUD operations by allowing developers to interact with the database using defined models rather than raw SQL.
  • Project setup involves installing `express`, the relevant SQL driver (e.g., `mysql2`), and `sequelize`, then configuring the database connection.

SQL Databases

SQL Databases are relational database management systems characterized by structured schemas, ACID compliance, and relational integrity. They are suitable for applications requiring strict data consistency and complex querying.

Key Facts:

  • SQL databases organize data into tables with predefined schemas, enforcing consistent data structures.
  • They ensure Atomicity, Consistency, Isolation, and Durability (ACID) for reliable transactions.
  • Foreign keys and joins maintain relationships between tables, making them suitable for complex, interconnected data.
  • Common examples include MySQL and PostgreSQL.
  • Scalability is traditionally vertical, though some support horizontal scaling through replication and sharding.

Node.js and Express Fundamentals

This module introduces Node.js as a runtime environment and Express.js as a web framework, covering essential concepts for backend development such as project setup, middleware, routing, and handling HTTP requests and responses. It emphasizes Node.js's event-driven, non-blocking I/O model and Express.js's minimal framework approach.

Key Facts:

  • Node.js is an event-driven, non-blocking I/O runtime environment suitable for scalable API development.
  • Express.js is a minimal and flexible Node.js web application framework that provides robust features for web and mobile applications.
  • Key topics include setting up a Node.js environment, managing dependencies with npm, understanding `package.json`, creating basic Express servers, and utilizing middleware for tasks like JSON body parsing and logging.
  • Middleware functions in Express.js have access to the request object, the response object, and the next middleware function in the application’s request-response cycle.
  • Basic file system operations and HTTP modules in Node.js are covered to provide a foundational understanding of server-side programming.

Express.js Middleware

This sub-topic explores the concept and application of middleware functions within Express.js, which are central to the request-response cycle. It explains how middleware can execute code, modify request/response objects, and control the flow of execution, including built-in and third-party solutions.

Key Facts:

  • Middleware functions in Express.js have access to the request object (`req`), the response object (`res`), and the `next` middleware function.
  • Middleware can execute any code, make changes to the request and response objects, and end the request-response cycle.
  • Calling `next()` passes control to the next middleware function; omitting it leaves the request hanging.
  • Express.js supports various types of middleware, including application-level, router-level, error-handling, built-in, and third-party options.
  • `express.json()` is a built-in middleware for parsing incoming JSON payloads, while `body-parser` offers broader support for various body types.

Express.js Routing

This sub-topic focuses on Express.js's robust routing capabilities, which enable applications to define how they respond to client requests based on specific URIs and HTTP methods. It covers route parameters and the use of route handlers to manage the request-response cycle.

Key Facts:

  • Express.js defines how an application responds to client requests at specific endpoints using HTTP methods.
  • Methods like `app.get()`, `app.post()`, `app.put()`, and `app.delete()` are used to handle different HTTP verbs.
  • Route parameters (e.g., `/users/:id`) capture values from the URL, accessible via `req.params`.
  • Regular expressions can be integrated with route parameters for more precise URL matching.
  • Multiple callback functions can be associated with a single route, acting as middleware, and can invoke `next('route')` to bypass subsequent handlers.

Express.js Server Creation

This sub-topic delves into the practical aspects of setting up basic web servers using Express.js. It highlights Express.js's role as a framework built upon Node.js's core HTTP module, simplifying server creation and management for web and mobile applications.

Key Facts:

  • Express.js is a minimal and flexible Node.js web application framework that streamlines server creation.
  • It provides a robust set of features for developing web applications and APIs, abstracting away complexities of the raw `http` module.
  • Compared to the Node.js `http` module, Express.js offers a higher level of abstraction and built-in tools for routing and middleware.
  • Express.js simplifies the process of setting up and managing web servers and routing requests.
  • The `http` module provides basic functionalities, while Express.js adds speed, ease of use, and a less cumbersome development experience.

Node.js Core Concepts

This sub-topic covers the foundational principles of Node.js, focusing on its event-driven, non-blocking I/O model and how the event loop enables concurrent operations. Understanding these core concepts is crucial for building efficient and scalable backend applications.

Key Facts:

  • Node.js is a JavaScript runtime environment that executes code outside a web browser, ideal for scalable API development.
  • It employs a non-blocking I/O model, allowing the program to continue execution while I/O operations run in the background, preventing bottlenecks.
  • The single-threaded event loop in Node.js continuously monitors for pending events and executes their associated callback functions.
  • Node.js achieves concurrency by offloading I/O tasks to the system kernel, simplifying development while maintaining high performance.
  • The event loop has several phases, including timers, pending callbacks, poll, check, and close callbacks, which dictate the order of callback execution.

npm and Project Structure

This sub-topic introduces npm (Node Package Manager) as the primary tool for managing dependencies and project scripts in Node.js applications. It covers the crucial role of the `package.json` file in defining project metadata and managing various types of dependencies.

Key Facts:

  • npm is essential for managing dependencies and project scripts in Node.js applications.
  • The `package.json` file contains metadata about the project, including its name, version, and author.
  • It lists both `dependencies` (required for project execution) and `devDependencies` (for development-only tasks).
  • Custom `scripts` defined in `package.json` automate tasks like running tests or starting a server.
  • `npm install` installs listed dependencies, and `npm init` helps create a structured `package.json` file.

RESTful API Design and Implementation

This module covers the principles of designing and implementing RESTful APIs using Node.js and Express, focusing on mapping HTTP methods to CRUD operations, structuring API routes, handling various request components, and implementing effective error handling strategies. It emphasizes creating maintainable and robust API endpoints.

Key Facts:

  • RESTful API design involves mapping HTTP methods (GET, POST, PUT, DELETE) to CRUD (Create, Read, Update, Delete) operations for resources.
  • Structuring API routes typically involves defining endpoints for collections (e.g., `/api/users`) and individual resources (e.g., `/api/users/:id`).
  • Request parameters (`/users/:id`), query strings (`/users?status=active`), and request bodies (for POST/PUT) are key components of handling client input.
  • Effective error handling, including centralized error handling middleware, is crucial for providing meaningful feedback to API consumers.
  • Tools like Postman or Insomnia are essential for testing API endpoints and verifying their functionality.

API Routing and Naming Conventions

This module details the best practices for structuring API routes and establishing consistent naming conventions to create maintainable and scalable RESTful APIs. It covers using nouns for resources, pluralization for collections, hierarchical structures, and practical considerations for versioning and query parameters, including modular routing in Express.js.

Key Facts:

  • URIs for RESTful APIs should use nouns to represent resources, not verbs, for example, `/users` instead of `/getUsers`.
  • Plural nouns should be used for collection URIs (e.g., `/products`), and singular nouns for individual resource URIs (e.g., `/products/{id}`).
  • Hierarchical structures should represent relationships between nested resources, such as `/customers/{customerId}/accounts`.
  • API versioning (e.g., `/api/v1/users`) is essential to manage changes without breaking existing client applications.
  • Modular routing using `express.Router()` in Express.js improves organization and maintainability for large APIs by grouping related endpoints.

Error Handling Strategies

This module focuses on implementing robust error handling strategies within RESTful APIs, particularly using centralized error handling middleware in Express.js. It emphasizes providing meaningful feedback to API consumers through appropriate HTTP status codes and informative, non-sensitive error messages, alongside logging for debugging.

Key Facts:

  • Robust error handling is crucial for providing meaningful feedback to API consumers and ensuring application stability.
  • Centralized error handling middleware in Express.js catches and manages errors from various parts of the application, preventing crashes and providing consistent responses.
  • Express error handling middleware functions require four arguments: `(err, req, res, next)`.
  • Error responses must include appropriate HTTP status codes (e.g., 400 Bad Request, 404 Not Found, 500 Internal Server Error) and clear, informative messages.
  • Error messages should avoid exposing sensitive internal application details, and errors should be logged for debugging and monitoring.

REST Principles and HTTP Methods

This module introduces the core principles of REST (Representational State Transfer) as an architectural style for networked applications, focusing on its reliance on standard HTTP methods for resource-based interactions. It explains how resources are identified by URIs and manipulated using HTTP verbs, ensuring stateless and consistent communication.

Key Facts:

  • REST is an architectural style that defines how different systems communicate over HTTP, prioritizing statelessness and resource-based interactions.
  • In REST, everything is a resource, identified by a Unique Resource Identifier (URI), representing entities in an application.
  • Standard HTTP methods (GET, POST, PUT, PATCH, DELETE) are mapped to CRUD operations for resources.
  • Statelessness dictates that each request from a client to a server must contain all necessary information, with the server not storing client context between requests.
  • The Uniform Interface principle ensures consistent API interaction through standard HTTP methods, URIs, and self-descriptive messages.

Testing API Endpoints

This module covers the essential methods and tools for testing RESTful API endpoints, primarily using Postman. It explains how to create, send, and analyze requests for all CRUD operations, and how to leverage Postman's features like collections and environment variables for efficient and organized testing.

Key Facts:

  • Tools like Postman or Insomnia are essential for testing API endpoints and verifying their functionality.
  • Postman allows users to create requests, select HTTP methods (GET, POST, PUT, DELETE), and specify API endpoint URLs.
  • After sending a request, Postman displays the server's response, including status code, headers, and response data (typically JSON).
  • Postman can be used to test all CRUD operations, such as sending a POST to create, GET to verify, and DELETE to remove a resource.
  • Postman collections help organize related API requests, and environment variables provide flexibility for different deployment environments.

Security Best Practices and Advanced Topics

This module covers essential security measures and advanced development topics for building production-grade Node.js/Express applications. It includes using `Helmet` for HTTP headers, rate limiting, input sanitization, environment variables, and explores advanced Node.js features and project structuring for scalability.

Key Facts:

  • Security best practices include using `Helmet` to set secure HTTP headers and implementing rate limiting with `express-rate-limit` to prevent brute-force attacks.
  • Input sanitization (e.g., with `express-validator`) is critical to mitigate injection vulnerabilities and ensure data integrity.
  • Environment variables, often managed with `dotenv`, are used to store sensitive configuration data securely outside the codebase.
  • HTTPS encryption is a must for secure communication in production environments, protecting data in transit.
  • Advanced topics include project structuring for maintainability, exploring Node.js Event Loop and Worker Threads, and adopting TypeScript for larger projects.

Environment Variables with dotenv

Environment variables are a method for securely storing sensitive configuration data outside the codebase, such as API keys and database credentials. The `dotenv` library is commonly used in Node.js development to load these variables from a `.env` file into `process.env`, enhancing security, flexibility, and maintainability.

Key Facts:

  • Environment variables store sensitive configuration data outside the codebase.
  • This practice enhances security, flexibility, and maintainability by keeping secrets out of version control.
  • The `dotenv` library is a popular choice for managing environment variables in Node.js during development.
  • `.env` files should never be committed to version control; `.env.example` files are used as templates.
  • For production, dedicated secret managers (e.g., AWS Secrets Manager) are preferred over `.env` files for enhanced security.

HTTPS Encryption

HTTPS encryption is fundamental for securing data in transit between clients and servers in production environments. It protects sensitive information from eavesdropping, tampering, and forgery by encrypting communication, thus ensuring confidentiality and integrity.

Key Facts:

  • HTTPS encryption is crucial for securing data in transit between clients and servers.
  • It protects sensitive information from eavesdropping and tampering.
  • HTTPS uses TLS/SSL protocols to encrypt communication.
  • Enforcing HTTPS prevents man-in-the-middle attacks.
  • Most modern web applications require HTTPS for various features and security policies, such as HSTS.

Input Sanitization and Validation with express-validator

Input sanitization and validation are crucial for protecting applications from vulnerabilities like SQL injection and XSS attacks by ensuring user input conforms to expected formats and is cleansed of harmful characters. Libraries like `express-validator` provide robust tools for both validating and sanitizing input in Express.js applications.

Key Facts:

  • Input validation ensures user input conforms to expected formats and constraints.
  • Input sanitization cleans input by removing or neutralizing potentially harmful characters or scripts.
  • These practices protect against SQL injection, XSS attacks, and malformed requests.
  • `express-validator` is a widely used library offering methods for both validation (e.g., `isEmail()`) and sanitization (e.g., `escape()`).
  • It is best practice to use middleware for centralized handling of validation and sanitization logic.

Node.js Event Loop and Worker Threads

The Node.js Event Loop is a core component that enables asynchronous, non-blocking I/O operations, making Node.js efficient for I/O-bound tasks. Worker Threads, introduced in Node.js v10.5.0, allow developers to offload CPU-intensive tasks to separate threads, preventing them from blocking the main Event Loop and improving application responsiveness and scalability.

Key Facts:

  • The Node.js Event Loop handles asynchronous operations, making Node.js efficient for I/O-bound tasks.
  • Node.js uses an internal thread pool (libuv) for heavier synchronous tasks like file system operations.
  • Worker Threads allow running CPU-intensive tasks in separate, parallel threads.
  • Worker Threads prevent CPU-intensive tasks from blocking the main Event Loop, enhancing responsiveness.
  • Each worker thread has its own V8 engine instance and memory space, communicating via a messaging system.

Project Structuring for Scalability and Maintainability with TypeScript

Effective project structuring is crucial for developing scalable and maintainable Node.js applications, especially as they grow in complexity. Adopting TypeScript further enhances code quality, readability, and developer experience by introducing static typing, making it an invaluable tool for larger projects.

Key Facts:

  • Effective project structuring organizes code into logical modules, separating concerns for maintainability.
  • TypeScript adds static typing to JavaScript, catching errors during development and improving code reliability.
  • TypeScript enhances IDE support with better autocompletion, navigation, and refactoring tools.
  • Static typing improves code clarity and readability, especially in collaborative environments.
  • Setting up TypeScript involves installing TypeScript and type definitions (e.g., `@types/express`) and configuring `tsconfig.json`.

Rate Limiting with express-rate-limit

Rate limiting is a critical security measure to prevent brute-force attacks and Denial-of-Service (DoS) attacks by controlling the number of requests a user or IP can make within a specified time frame. The `express-rate-limit` middleware is commonly used to implement this functionality in Express.js applications.

Key Facts:

  • Rate limiting prevents brute-force and Denial-of-Service (DoS) attacks.
  • It restricts the number of requests a user can make within a defined timeframe.
  • The `express-rate-limit` middleware is a common tool for implementing rate limiting in Express.js applications.
  • Rate limiting can be configured globally or per-route to protect specific endpoints.
  • Exceeding the rate limit typically results in an HTTP 429 Too Many Requests response.

Secure HTTP Headers with Helmet.js

Secure HTTP Headers with Helmet.js focuses on using the Helmet middleware to set various HTTP headers, thereby enhancing the security of Express.js applications against common web vulnerabilities. Helmet helps mitigate attacks like XSS, clickjacking, and MIME-sniffing by configuring security-related response headers.

Key Facts:

  • Helmet.js is an Express.js middleware that sets various HTTP headers to enhance application security.
  • It protects against attacks such as Cross-Site Scripting (XSS), clickjacking, and MIME-sniffing.
  • Key headers set by Helmet include Content-Security-Policy (CSP), X-Content-Type-Options, X-Frame-Options, Strict-Transport-Security (HSTS), and Referrer-Policy.
  • CSP mitigates XSS by specifying allowed dynamic resources, while HSTS enforces secure HTTPS communication.
  • Helmet is a component of a comprehensive security strategy, not a standalone solution for all vulnerabilities.

User Authentication and Authorization

This module focuses on implementing secure user authentication and authorization mechanisms for Node.js/Express applications. It covers token-based authentication (JWT), session-based authentication, password hashing with Bcrypt, and authorization techniques such as Role-Based Access Control (RBAC).

Key Facts:

  • Secure user authentication is implemented using methods like token-based (JWT) and session-based authentication.
  • JSON Web Tokens (JWTs) are popular for stateless authentication, allowing scalability without server-side session storage.
  • Password hashing with strong algorithms like Bcrypt, including salting, is paramount for securing user credentials.
  • Authorization techniques such as Role-Based Access Control (RBAC) are used to restrict access to resources based on user roles.
  • Best practices for JWTs include generating and verifying tokens, using short-lived access tokens with refresh tokens, and securing refresh tokens.

Passport.js for Authentication

Passport.js is a flexible and modular authentication middleware for Node.js and Express.js applications, simplifying the integration of various authentication strategies. It supports diverse methods including local, OAuth, and JWT strategies.

Key Facts:

  • Passport.js is a modular authentication middleware for Node.js and Express.js.
  • It supports a wide range of authentication strategies (local, OAuth, JWT) encapsulated in separate modules.
  • Passport integrates seamlessly into the Express.js request/response cycle.
  • It provides mechanisms for serialization and deserialization of user objects for session-based authentication.
  • Passport simplifies the setup of complex authentication flows in Node.js applications.

Password Hashing with Bcrypt

Bcrypt is a robust password hashing function designed to securely store user passwords by being resistant to brute-force attacks. It incorporates salting and a cost factor to enhance security, making it a critical component of user authentication.

Key Facts:

  • Bcrypt is a robust password hashing function known for its resistance to brute-force attacks.
  • It automatically generates a unique salt for each password, preventing rainbow table attacks.
  • Bcrypt allows adjusting the 'cost factor' to control the computational expense of the hashing process.
  • Increasing the cost factor makes hashing slower, thus increasing the resources needed for attackers.
  • The `bcrypt` or `bcryptjs` libraries are used in Node.js to hash and compare passwords.

Role-Based Access Control (RBAC)

Role-Based Access Control (RBAC) is an authorization technique that manages user permissions by assigning predefined roles, each with specific sets of permissions. This method simplifies access control and ensures users can only access resources relevant to their assigned roles.

Key Facts:

  • RBAC manages user permissions by assigning predefined roles rather than direct permissions.
  • Permissions are grouped into roles (e.g., 'admin', 'editor', 'viewer').
  • Users inherit permissions associated with the roles they are assigned.
  • RBAC can be implemented in Node.js using middleware to check user roles and permissions.
  • Libraries like Oso Cloud offer tools for defining and enforcing RBAC policies.

Session-Based Authentication

Session-Based Authentication involves storing user session data on the server and issuing a session ID to the client, typically as a cookie. This method contrasts with token-based authentication by maintaining server-side state for user sessions.

Key Facts:

  • Session-based authentication stores user session data on the server, often in a dedicated session store.
  • Upon login, a session is created on the server, and a unique session ID is sent to the client as a cookie.
  • The client includes the session ID cookie in subsequent requests for the server to retrieve session information.
  • The `express-session` middleware is commonly used for session management in Express.js.
  • Redis is frequently employed as a high-performance session store, especially in production environments, using libraries like `connect-redis`.

Token-Based Authentication (JWT)

Token-Based Authentication, specifically using JSON Web Tokens (JWTs), offers a stateless authentication mechanism ideal for scalable applications. This method involves the server generating a JWT upon successful login, which the client then stores and includes in subsequent requests for verification.

Key Facts:

  • JWTs provide stateless authentication, enabling scalability without server-side session storage.
  • A JWT consists of a header, a payload, and a signature.
  • Clients typically store JWTs in localStorage or HttpOnly cookies and send them in the authorization header.
  • Best practices for JWTs include using short-lived access tokens, refresh tokens, and securing the secret key.
  • Libraries like `jsonwebtoken` are used in Node.js for creating and verifying JWTs.