72-Nodejs Course 2023: The Bloody Cors
Tags: node, typescript, mongodb, fastify
Published: 2022-11-26 15:39:55

---
title: 72-Nodejs Course 2023: The Bloody Cors
published: true
description: 
series: Nodejs Course 2023
tags: nodejs, typescript, mongodb, fastify
cover_image: https://dev-to-uploads.s3.amazonaws.com/uploads/articles/i4khu87dqutqttqxh8jw.png
# Use a ratio of 100:42 for best results.
---

## What is CORS?

**CORS** stands for `Cross-Origin Resource Sharing`. It is a mechanism that allows restricted resources on a web page to be requested from another domain outside the domain from which the first resource was served. A web page may freely embed cross-origin images, stylesheets, scripts, iframes, and videos. Certain "cross-domain" requests, notably Ajax requests, are forbidden by default by the same-origin security policy.

## In Simple Words?

Simply put, `Cors` allows us to whitelist the domains that can access our API. It is a security mechanism that prevents unauthorized access to our API.

For example, our nodejs application is going to be `API` application, so we can define who is allowed to access our API. For example, we can allow `localhost:3000` to access our API, but we can also allow `localhost:3001` to access our API. So, we can define a list of domains that are allowed to access our API.

So it is a sort of a `middleware` as well such as our previous `throttle` article one.

## How does Cors work?

It basically has multiple functionalities, it can white/black list any of the following:

- Certain Domains
- Certain HTTP Methods
- Certain HTTP Headers

## What is an Origin?

An origin is a combination of URI scheme, host name, and port number. For example, `https://www.example.com:443` is an origin. The origin of a resource is the origin of the server that served the resource. For example, if you visit `https://www.example.com:443` and it returns a resource that has a URL of `https://www.example.com:443/foo/bar`, the origin of the resource is `https://www.example.com:443`.

So we can simply say that `origin` is the combination of `protocol`, `domain`/ `sub-domain` and `port`.

## Preflight Request

When a request is made to an API, the browser will first send a `preflight` request to the API to check if the request is allowed. If the request is allowed, then the browser will send the actual request.

### What is a Preflight Request?

A preflight request is simply a `OPTIONS` request that is sent to the API to check if the request is allowed. If the request is allowed, then the browser/client side will send the actual request such as `GET`, `POST`, `PUT`, `DELETE` etc.

That's where mostly the `OPTIONS` request method is used in.

## How to Implement?

We can use [fastify-cors](https://github.com/fastify/fastify-cors) plugin to implement `Cors` in our application.

## Installation

```bash
yarn add @fastify/cors
```

## Usage

As mentioned in the docs, we need first to register our plugin and its options.

> We're going to use the dynamic import as we did earlier to import our plugin.

```ts
// src/core/http/plugins.ts
import fastifyJwt from "@fastify/jwt";
import fastifyMultipart from "@fastify/multipart";
import { registerPlugin } from "./server";

export default async function registerHttpPlugins() {
  // 👇🏻 register rate-limit plugin
  await registerPlugin(import("@fastify/rate-limit"), {
    // max requests per time window
    max: 10,
    // maximum time that is will allow max requests
    timeWindow: 60 * 1000,
  });

  // 👇🏻 register cors plugin
  await registerPlugin(import("@fastify/cors"), {
    // options list
  });

  // import multipart plugin
  registerPlugin(fastifyMultipart, {
    attachFieldsToBody: true,
  });

  // use the jwt plugin with your preferred secret key
  registerPlugin(fastifyJwt, {
    secret: "my-secret",
  });
}
```

Nothing new here, we just imported our new cors plugin.

## Options

We can pass options to our cors plugin, for example, we can allow `localhost:3000` to access our API.

```ts
// src/core/http/plugins.ts
import fastifyJwt from "@fastify/jwt";

/// ...

// 👇🏻 register cors plugin
await registerPlugin(import("@fastify/cors"), {
// options list
origin: ["http://localhost:3000"],
});
```

In the previous code, we allowed `localhost:3000` to access our API, so any other origin will not be allowed to access our API.

## Allowing All Origins

We can also allow all origins to access our API, but this is not recommended `as it is a security risk.`

```ts
// src/core/http/plugins.ts
import fastifyJwt from "@fastify/jwt";

/// ...

// 👇🏻 register cors plugin
await registerPlugin(import("@fastify/cors"), {
// options list
origin: "*",
});
```

This will allow all origins to access our API.

## Black/White Listing Origins

The plugin doesn't give as the ability to whitelist/blacklist certain HTTP methods, so we need to do it manually, this can be done by using custom `origin` function.

```ts
// src/core/http/plugins.ts
import fastifyJwt from "@fastify/jwt";

/// ...

// 👇🏻 register cors plugin
await registerPlugin(import("@fastify/cors"), {
// options list
origin: (origin, callback) => {
  // whitelist certain domains
  if (origin === "http://localhost:3000") {
    callback(null, true);
    return;
  }

  // blacklist certain domains
  if (origin === "http://localhost:3001") {
    callback(new Error("Not allowed"), false);
    return;
  }

  // allow all origins
  callback(null, true);
},
});
```

Of course we are not going to use it like this, i'm just giving an example of how we can implement it later, this can be in our next `Break` article or so.

## Why am i calling it Bloody CORS? 😁

Well, because when i started working with APIs, it was really pretty annoying to me to understand how it works and apply it with my Client side applications that connects to my API Applications, i was always getting an error message because of Cors says: `No 'Access-Control-Allow-Origin' header is present on the requested resource.`

That's why i was (and still) calling it `Bloody CORS` 😁

## 🎨 Conclusion

In this article, we learned how to implement `Cors` in our application, we also learned what is `Cors` and how it works.

We didn't set any configurations yet for our `Cors` plugin, we will do it later as we go through our application.

## ☕♨️ Buy me a Coffee ♨️☕

If you enjoy my articles and see it useful to you, you may [buy me a coffee](https://www.paypal.com/paypalme/hassanzohdy), it will help me to keep going and keep creating more content.

## 🚀 Project Repository

You can find the latest updates of this project on [Github](https://github.com/hassanzohdy/nodejs-2023)

## 😍 Join our community

Join our community on [Discord](https://discord.gg/pb2vmdfhGf) to get help and support (Node Js 2023 Channel).

## 🎞️ Video Course (Arabic Voice)

If you want to learn this course in video format, you can find it on [Youtube](https://www.youtube.com/playlist?list=PLGO8ntvxgiZMJc7RN2lIq9WmMOlWZGzmz), the course is in Arabic language.

## 📚 Bonus Content 📚

You may have a look at these articles, it will definitely boost your knowledge and productivity.

General Topics

- [Event Driven Architecture: A Practical Guide in Javascript](https://dev.to/hassanzohdy/event-driven-architecture-the-best-paradigm-that-i-love-to-work-with-in-javascript-and-node-js-1gnk)
- [Best Practices For Case Styles: Camel, Pascal, Snake, and Kebab Case In Node And Javascript](https://dev.to/hassanzohdy/best-practices-for-case-styles-camel-pascal-snake-and-kebab-case-in-node-and-javascript-55oi)
- [After 6 years of practicing MongoDB, Here are my thoughts on MongoDB vs MySQL
](https://dev.to/hassanzohdy/after-6-years-of-practicing-mongodb-here-are-my-thoughts-on-mongodb-vs-mysql-574b)

Packages & Libraries

- [Collections: Your ultimate Javascript Arrays Manager](https://dev.to/hassanzohdy/collections-your-ultimate-javascript-array-handler-3o15)
- [Supportive Is: an elegant utility to check types of values in JavaScript](https://dev.to/hassanzohdy/supportive-is-an-elegant-utility-to-check-types-of-values-in-javascript-1b3e)
- [Localization: An agnostic i18n package to manage localization in your project](https://dev.to/hassanzohdy/mongez-localization-the-simplest-way-to-translate-your-website-regardless-your-favorite-framework-4gi3)

 React Js Packages

- [useFetcher: easiest way to fetch data in React Js](https://dev.to/hassanzohdy/usefetcher-the-easiest-way-to-fetch-data-in-react-45o9)

Courses (Articles)

- [OOP In JS And TS From The Very Beginning](https://dev.to/hassanzohdy/jsts-oop-course-1-introduction-2ld)
- [ES6++: The Ultimate Guide to ES6 and Beyond](https://dev.to/hassanzohdy/es6-1-introduction-h3e)
- [React Js: Let"s Create File Manager With React Js and Node Js](https://dev.to/hassanzohdy/lets-create-a-file-manager-from-scratch-with-react-and-typescript-chapter-i-a-good-way-to-expand-your-experience-5g4k)