Créer un site comme Facebook est un projet ambitieux qui nécessite une infrastructure robuste et des fonctionnalités complexes comme l'authentification des utilisateurs, la gestion des publications, les messages privés, les notifications, etc. Voici un projet de base en MERN Stack (MongoDB, Express.js, React.js, Node.js) qui comprend :

  • Un backend en Node.js/Express.js pour gérer l’authentification et les publications.
  • Une base de données MongoDB pour stocker les utilisateurs et les publications.
  • Un frontend en React.js pour l’interface utilisateur.

1. Installation des dépendances

Avant de commencer, assure-toi d’avoir Node.js et MongoDB installés. Puis, crée les dossiers :

mkdir my-facebook-clone
cd my-facebook-clone

Crée deux sous-dossiers :

mkdir backend frontend

2. Backend (Node.js + Express + MongoDB)

a) Installe les dépendances backend

cd backend
npm init -y
npm install express mongoose cors dotenv bcryptjs jsonwebtoken

b) Crée le fichier .env pour les variables d’environnement

PORT=5000
MONGO_URI=your_mongodb_connection_string
JWT_SECRET=your_secret_key

c) Structure du backend

Crée les fichiers suivants :

backend/
│── server.js
│── models/
│   ├── User.js
│   ├── Post.js
│── routes/
│   ├── authRoutes.js
│   ├── postRoutes.js
│── middleware/
│   ├── authMiddleware.js

d) Modèle utilisateur (models/User.js)

const mongoose = require("mongoose");

const UserSchema = new mongoose.Schema({
    username: { type: String, required: true, unique: true },
    email: { type: String, required: true, unique: true },
    password: { type: String, required: true },
}, { timestamps: true });

module.exports = mongoose.model("User", UserSchema);

e) Modèle publication (models/Post.js)

const mongoose = require("mongoose");

const PostSchema = new mongoose.Schema({
    userId: { type: mongoose.Schema.Types.ObjectId, ref: "User", required: true },
    content: { type: String, required: true },
}, { timestamps: true });

module.exports = mongoose.model("Post", PostSchema);

f) Routes d’authentification (routes/authRoutes.js)

const express = require("express");
const bcrypt = require("bcryptjs");
const jwt = require("jsonwebtoken");
const User = require("../models/User");
const router = express.Router();

// Inscription
router.post("/register", async (req, res) => {
    const { username, email, password } = req.body;
    const hashedPassword = await bcrypt.hash(password, 10);
    const newUser = new User({ username, email, password: hashedPassword });

    try {
        await newUser.save();
        res.status(201).json("Utilisateur créé !");
    } catch (err) {
        res.status(500).json(err);
    }
});

// Connexion
router.post("/login", async (req, res) => {
    const { email, password } = req.body;
    try {
        const user = await User.findOne({ email });
        if (!user) return res.status(404).json("Utilisateur non trouvé");
        
        const validPassword = await bcrypt.compare(password, user.password);
        if (!validPassword) return res.status(400).json("Mot de passe incorrect");

        const token = jwt.sign({ id: user._id }, process.env.JWT_SECRET);
        res.json({ token, user });
    } catch (err) {
        res.status(500).json(err);
    }
});

module.exports = router;

g) Middleware d’authentification (middleware/authMiddleware.js)

const jwt = require("jsonwebtoken");

module.exports = (req, res, next) => {
    const token = req.header("Authorization");
    if (!token) return res.status(401).json("Accès refusé");

    try {
        const verified = jwt.verify(token, process.env.JWT_SECRET);
        req.user = verified;
        next();
    } catch (err) {
        res.status(400).json("Token invalide");
    }
};

h) Routes des publications (routes/postRoutes.js)

const express = require("express");
const Post = require("../models/Post");
const authMiddleware = require("../middleware/authMiddleware");

const router = express.Router();

// Créer une publication
router.post("/", authMiddleware, async (req, res) => {
    const newPost = new Post({ userId: req.user.id, content: req.body.content });
    try {
        await newPost.save();
        res.status(201).json(newPost);
    } catch (err) {
        res.status(500).json(err);
    }
});

// Récupérer toutes les publications
router.get("/", async (req, res) => {
    try {
        const posts = await Post.find().populate("userId", "username");
        res.json(posts);
    } catch (err) {
        res.status(500).json(err);
    }
});

module.exports = router;

i) Serveur principal (server.js)

const express = require("express");
const mongoose = require("mongoose");
const cors = require("cors");
const dotenv = require("dotenv");
const authRoutes = require("./routes/authRoutes");
const postRoutes = require("./routes/postRoutes");

dotenv.config();
const app = express();
app.use(express.json());
app.use(cors());

mongoose.connect(process.env.MONGO_URI)
    .then(() => console.log("MongoDB connecté"))
    .catch(err => console.log(err));

app.use("/api/auth", authRoutes);
app.use("/api/posts", postRoutes);

app.listen(process.env.PORT, () => console.log("Serveur lancé sur le port", process.env.PORT));

3. Frontend (React.js + Axios + TailwindCSS)

a) Installe React et les dépendances

cd ../frontend
npx create-react-app .
npm install axios react-router-dom tailwindcss

b) Configuration de TailwindCSS

Ajoute ceci à tailwind.config.js :

module.exports = {
  content: ["./src/**/*.{js,jsx}"],
  theme: {
    extend: {},
  },
  plugins: [],
}

Ajoute Tailwind dans index.css :

@tailwind base;
@tailwind components;
@tailwind utilities;

c) Composant d’authentification (Auth.js)

import { useState } from "react";
import axios from "axios";

export default function Auth() {
  const [email, setEmail] = useState("");
  const [password, setPassword] = useState("");

  const login = async () => {
    const res = await axios.post("http://localhost:5000/api/auth/login", { email, password });
    localStorage.setItem("token", res.data.token);
  };

  return (
    <div>
      <input type="text" placeholder="Email" onChange={(e) => setEmail(e.target.value)} />
      <input type="password" placeholder="Mot de passe" onChange={(e) => setPassword(e.target.value)} />
      <button onClick={login}>Connexion</button>
    </div>
  );
}

Ce projet est un point de départ. Pour aller plus loin, il faudrait ajouter des fonctionnalités comme la gestion des amis, des messages privés et une meilleure interface utilisateur.

Commentaires

Posts les plus consultés de ce blog