Building a Subscription- Based Video Course Website with Node.js, Express, and Firebase

Building a Subscription- Based Video Course Website with Node.js, Express, and Firebase

Introduction

In this blog post, we will explore the process of building a subscription-based video course website using Node.js, Express, and Firebase. This project aims to provide users with a seamless registration and login experience, secure video content, and efficient hosting and deployment using render.com and a custom domain from Hostinger. I recently had the opportunity to build this exact website for a client, and I am excited to share my experience and insights with you.

Understanding the Project Scope:

The first step in any development project is to grasp the client's requirements. In this case, the client wanted to sell video content through a subscription-based model. To streamline the registration process, Google Forms were integrated into the signup page as requested by the client. Once registered and the payment is completed, users receive the password for their account and gain access to the video section.

Setting up the Backend with Node.js and Express:

Node.js and Express were chosen as the backend technologies to handle server-side logic and routing. Express provided a convenient framework for creating routes, handling HTTP requests, and rendering views. By structuring the application using routes, different pages such as home, gallery, syllabus, about, videos, contact, signup, and login were implemented.

To implement the signup and login functionality, I incorporated JavaScript and Firebase into the website's login page. Using a script tag, I connected the login page to the Firebase backend by initializing the Firebase configuration object. The login page featured a form where users could enter their email and password. When the user submits the form, the email and password are collected and checked using the following code:

firebase
  .auth()
  .signInWithEmailAndPassword(email, password)
  .then(({ user }) => {
    return user.getIdToken().then((idToken) => {
      return fetch("/sessionLogin", {
        method: "POST",
        headers: {
          Accept: "application/json",
          "Content-Type": "application/json",
        },
        body: JSON.stringify({ idToken }),
      });
    });
  })
  .then(() => {
    return firebase.auth().signOut();
  })
  .then(() => {
    window.location.assign("/videos");
  })
  .catch((error) => {
    // Display the error message and hide the loading animation
    errorElement.style.display = "block";
    loadingElement.style.display = "none";
  });

This code utilizes the Firebase authentication methods to sign in the user with the provided email and password. If the credentials are correct, a Firebase ID token is obtained, and a POST request is made to the /sessionLogin endpoint. This endpoint securely stores the user's session using appropriate security measures, allowing the user to access protected areas of the website, such as the video page. After successful authentication and session creation, the user is redirected to the videos page. In case of invalid credentials, an error message is displayed to the user.

Firebase played a crucial role in this process by providing convenient authentication methods, handling password storage and verification, and managing user sessions securely.

For the signup page, I implemented a straightforward approach by embedding a link to a Google Form. Upon accessing the signup page, users are directed to the Google Form where they can enter their details, such as their name and email address. Once the user submits the form, the data is collected by the Google Form and forwarded directly to the client. The client then takes the responsibility of setting up the credentials for the new user, including the password.

To facilitate this process, I utilized the email/password feature of Firebase authentication. By enabling this feature, the client could easily add the user to Firebase and set up their password. Firebase provided a secure and efficient way to manage user authentication, allowing the client to handle the creation of user accounts with personalized credentials. This integration between the Google Form for data collection and Firebase for user management ensured a seamless signup process and enhanced security for the website's users.

Video Section and Access Control

The video section of the website was a crucial feature that required careful implementation. To host the videos, I integrated a reliable video hosting platform called bunny.net. This dedicated platform provided robust security features that were essential for protecting video content. One of the key requirements set by the client was to restrict access to the videos only to logged-in users. To achieve this, I implemented a session-based authentication system. When a user logs in with their credentials, a session cookie is generated using the following code:

app.post("/sessionLogin", (req, res) => {
  const idToken = req.body.idToken.toString();
  const expiresIn = 60 * 60 * 24 * 1  * 1000;

  admin
    .auth()
    .createSessionCookie(idToken, { expiresIn })
    .then(
      (sessionCookie) => {
        const options = { maxAge: expiresIn, httpOnly: true };
        res.cookie("session", sessionCookie, options);
        res.end(JSON.stringify({ status: "success" }));
      },
      (error) => {
        res.status(401).send("UNAUTHORIZED REQUEST!");
      }
    );
});

The session cookie allows authorized users to access the video section for a duration of one day. If a user logs out, the session cookie is automatically cleared, ensuring that access is revoked and the user is redirected to the home page.

In addition to the session-based authentication, the videos themselves are protected with additional security measures provided by bunny.net. These measures ensure that the videos can only be played on the specific domain where they are hosted, making them non-sharable. This adds an extra layer of security, preventing unauthorized distribution or playback of the videos.

By combining the session-based authentication system and the security features of bunny.net, I was able to create a secure video section that allowed only authorized users to access and view the course content, safeguarding valuable video materials.

Exploring Additional Pages and Features

In addition to the video section, I also developed several other pages to fulfill the client's requirements. The home page served as the landing page, providing an introduction to the website and highlighting the key features. The about page provided detailed information about the client, including their background, expertise, and achievements. The syllabus page presented an organized outline of the course content, allowing users to gain a comprehensive understanding of what they could expect from the course. Additionally, the gallery page showcased visual content related to the course or the client's work, creating an engaging and visually appealing experience for visitors.

Overall, these additional pages and features contributed to a well-rounded website that effectively showcased the client's expertise, provided relevant course information, and created an engaging user experience.

Conclusion

In conclusion, this project involved the successful development of a website for selling video content through a subscription model. By implementing user authentication, video hosting, and access control, the website provides a secure platform for delivering valuable course materials. The client expressed satisfaction with the final product, which enables them to safely share their videos with registered users. Through this project, I gained valuable experience in utilizing technologies like HTML, CSS, JavaScript, Node.js, Express, Firebase, and bunny.net. Moving forward, potential improvements include streamlining the payment process and exploring additional security measures for video hosting.

You can find the project's code and implementation on GitHub: https://github.com/Niranjangkr/webisteLearnFInance.git. This project has allowed me to enhance my web development skills and provided valuable insights into building functional and secure websites. I look forward to applying this knowledge in future projects and continuing to refine my abilities in website development.

Did you find this article valuable?

Support Niranjan Gaonkar by becoming a sponsor. Any amount is appreciated!