Building a Car Marketplace Web Application: A Full-Stack Journey

Welcome to my development journey in building a Car Marketplace Web Application from scratch! In this blog post, we'll dive into the technical aspects of user authorization, login, and session management in the backend, as well as the creation of a user-friendly frontend using Next.js.


Backend: User Authorization and Session Management

Introduction

User authorization and session management are fundamental pillars of modern web applications. These elements ensure secure access and seamless user experiences. In this project, I harnessed the power of Python and Flask to handle these crucial tasks effectively.

User Authentication

User authentication is the foundation of user security. It involves verifying user identities before granting access to protected resources. To achieve this, I implemented a robust user authentication system using Flask-Bcrypt. Let's take a closer look at how it works:

# app.py (Backend)
from flask_bcrypt import Bcrypt

app = Flask(__name__)
flask_bcrypt = Bcrypt(app)

# ... (other code)

class User(db.Model, SerializerMixin):
    # ...

    @hybrid_property
    def password_hash(self):
        raise ValueError("Password hash is private")

    @password_hash.setter
    def password_hash(self, password):
        self._password_hash = flask_bcrypt.generate_password_hash(password).decode("utf-8")

    def authenticate(self, password):
        return flask_bcrypt.check_password_hash(self._password_hash, password)

# ... (other code)

Session Management for a Seamless Experience

Session management is the key to maintaining a seamless user experience across interactions. After a successful login, a session ID is generated and stored in the Flask session. This ID is also added to a GLOBAL_SESSIONS set, indicating an active session. The user's ID is securely stored in the session, enabling personalized data retrieval.

Here's how the session management is implemented:

# app.py (Backend)
from flask import session
from random import randrange

@app.route("/login", methods=["POST"])
def login():
    # ...
    flask_session["user_id"] = user.id
    flask_session["session_id"] = randrange(0, 1e18)
    GLOBAL_SESSIONS.add(flask_session["session_id"])
    return user.to_dict(rules=("-cars",))

@app.route("/logout", methods=["DELETE"])
def logout():
    flask_session["user_id"] = None
    GLOBAL_SESSIONS.remove(flask_session["session_id"])
    return {}, 204

In this snippet, the /login endpoint sets the user_id and generates a unique session_id upon successful authentication. This session ID is added to the GLOBAL_SESSIONS set to keep track of active sessions. The /logout endpoint removes the session ID, effectively ending the user's session.

Retrieving Session Data

To maintain session persistence, the /session endpoint is crucial. It retrieves user-specific data using the stored session ID:

# app.py (Backend)
@app.route("/session")
def session():
    user = User.query.filter(User.id == flask_session.get("user_id")).first()
    if (
        "session_id" not in flask_session
        or flask_session["session_id"] not in GLOBAL_SESSIONS
    ):
        return {"error": "Please login"}, 401
    return user.to_dict(rules=("-cars",))

This endpoint retrieves the user's session ID from the Flask session and validates it against the GLOBAL_SESSIONS set. If the session ID is missing or invalid, the endpoint returns an error message, prompting the user to log in. When the session is valid, the user's data (with the list of cars excluded for privacy) is returned.

Frontend: Crafting an Intuitive User Interface

Introduction

The frontend of the Car Marketplace Web Application is designed to provide an engaging and user-friendly experience for exploring car listings and transactions. It's built using Next.js, a powerful React framework that offers server-rendered pages and optimized performance.

Core Technologies

The frontend architecture is centered around Next.js, which empowers us to create dynamic and responsive web applications. Here are the key technologies that contribute to the success of the frontend:

  • Next.js: The foundation of the frontend, offering server-rendered pages and optimized performance.

  • Next Router: Facilitating seamless navigation between different sections of the application.

  • React: Empowering the creation of interactive user interfaces using components and state management.

  • Tailwind CSS: Enhancing the user experience with stylish and responsive designs.

Project Structure

The frontend is organized into various components and routes, ensuring a modular and maintainable codebase. Some essential components include:

  • RootLayout: Serving as the highest-level layout component, providing a consistent structure across different pages.

  • UserContext: Managing user data and authentication status, making it available throughout the application.

  • Login: Handling user authentication by sending login requests to the backend API.

  • Nav: The navigation component ensuring consistent navigation throughout the app.

  • SellCar, ProfilePage, Register, Transactions, Mycars, cars, carId: Different routes catering to listing cars, user profiles, registration, transaction history, and more.

Conclusion

We've explored the intricate aspects of user authorization, login, and session management on the backend, and the art of creating a user-friendly frontend using Next.js. By combining Flask's powerful capabilities with Next.js's dynamic features, we've constructed a functional Car Marketplace Web Application.

Feel free to dive into the complete codebase on GitHub to further understand the implementation details.

Demo