on
Frameworks coté Serveur
Master 2 – Développement Web (Partie 1)
Vers une application Web complète : SSR + ORM + Auth
Introduction à Next.js, Prisma et Authentification
Objectifs du cours
- Comprendre la structure d’une application Web full-stack moderne.
- Découvrir Next.js (rendu serveur et routes API).
- Gérer la persistance des données avec Prisma ORM.
- Implémenter les bases de l’authentification (NextAuth.js).
- Préparer le TP1 – Application de gestion d’annonces immobilières.
1. La “Big Picture” – Comment tout s’articule
Une application Web moderne repose sur trois couches principales :
Couche | Rôle | Outil choisi |
---|---|---|
Interface (Frontend) | Ce que voit l’utilisateur : pages, formulaires, navigation | React (via Next.js) |
Logique Serveur (Backend) | Traitement des requêtes, génération des pages, API | Next.js (API Routes) |
Données (Base + ORM) | Stockage et accès aux informations persistantes | Prisma + PostgreSQL |
Sécurité (Auth) | Gestion des utilisateurs, sessions, permissions | NextAuth.js |
💡 Le tout fonctionne dans un seul projet TypeScript grâce à Next.js.
Exemple : flux complet d’une page “Annonces”
- Un utilisateur visite
/annonces
. - Next.js exécute du code serveur → va chercher les annonces via Prisma dans la base.
- La page est rendu côté serveur (SSR) et envoyée au navigateur.
- Si l’utilisateur est connecté (via NextAuth.js), il peut créer une annonce.
- Les actions (POST, DELETE…) passent par les API Routes internes à Next.js.
Navigateur ──▶ Next.js (SSR) ──▶ Prisma ──▶ Base de données
▲ │
│ └──▶ API /auth (NextAuth.js)
│
└──◀─── Données + HTML
Choix d’architecture
Concept | Avantage pédagogique |
---|---|
SSR (Server-Side Rendering) | Pages dynamiques rapides, SEO friendly, code React réutilisé |
ORM (Prisma) | Moins d’erreurs SQL, typage fort, génération automatique de requêtes |
Auth.js | Authentification intégrée à Next.js, rôles et sessions faciles |
TypeScript | Sécurité du typage du front au back |
Full-stack intégré | Pas besoin de gérer deux serveurs distincts (front/back) |
2. Créer un projet Next.js (base technique)
npx create-next-app@latest immobilier-app --typescript --tailwind --app
cd immobilier-app
npm run dev
Structure du dossier :
immobilier-app/
├─ src/
│ ├─ app/
│ │ ├─ page.tsx # Page d’accueil
│ │ ├─ about/page.tsx # Page "about"
│ │ ├─ annonces/[id]/page.tsx # Page dynamique
│ │ └─ api/ # Routes backend
│ └─ lib/ # outils (prisma, auth, etc.)
└─ package.json
3. Pages et navigation
Chaque dossier sous src/app
correspond à une route.
Exemple : page statique
// src/app/about/page.tsx
export default function AboutPage() {
return <h1>À propos de notre agence immobilière</h1>
}
Exemple : page dynamique avec paramètre
// src/app/annonces/[id]/page.tsx
export default function AnnoncePage({ params }: { params: { id: string } }) {
return <h1>Annonce n°{params.id}</h1>
}
➜ http://localhost:3000/annonces/12
4. Rendu SSR (Server-Side Rendering)
Les composants dans le dossier src/app/
peuvent être asynchrones :
On peut directement y faire des requêtes côté serveur.
// src/app/page.tsx
async function getData() {
const annonces = [
{ id: 1, titre: "Appartement Paris 11e" },
{ id: 2, titre: "Maison Bordeaux" },
]
return annonces
}
export default async function HomePage() {
const annonces = await getData()
return (
<ul>
{annonces.map(a => (
<li key={a.id}>{a.titre}</li>
))}
</ul>
)
}
5. Créer une API backend dans Next.js
Chaque fichier dans src/app/api/...
devient une route API.
// src/app/api/hello/route.ts
export async function GET() {
return Response.json({ message: "Bonjour depuis l’API Next.js !" })
}
➜ http://localhost:3000/api/hello
Exemple API avec POST
// src/app/api/messages/route.ts
let messages: string[] = []
export async function GET() {
return Response.json(messages)
}
export async function POST(req: Request) {
const { content } = await req.json()
messages.push(content)
return Response.json({ ok: true })
}
6. Persistance des données avec Prisma ORM
Prisma est un ORM moderne pour TypeScript : il traduit les modèles d’objets en tables SQL.
Installation
npm install @prisma/client prisma
npx prisma init
Cela crée un dossier prisma/
avec un fichier
schema.prisma`.
Exemple de modèle
// prisma/schema.prisma
datasource db {
provider = "sqlite" // PostgreSQL par défaut
url = "file:./dev.db"
}
generator client {
provider = "prisma-client-js"
// ⚠ pas de clé "output" pour rester compatible averc Next
}
model Annonce {
id Int @id @default(autoincrement())
titre String
description String
prix Float
statut Statut @default(PUBLIE)
createdAt DateTime @default(now())
}
enum Statut {
BROUILLON
PUBLIE
}
Puis :
npx prisma migrate dev --name init
Tester la création d’une annonce
Depuis une interface graphique :
npx prisma studio
Depuis le code :
// scripts/seed.ts
import { PrismaClient } from "@prisma/client"
const prisma = new PrismaClient()
async function main() {
await prisma.annonce.create({
data: {
titre: "Appartement Paris 11e",
description: "Bel appartement 2 pièces",
prix: 450000,
},
})
}
main()
7. Utiliser Prisma dans Next.js
On déclare un client partagé :
// src/lib/prisma.ts
import { PrismaClient } from "@prisma/client"
const globalForPrisma = global as unknown as { prisma: PrismaClient }
export const prisma =
globalForPrisma.prisma ||
new PrismaClient({
log: ["query"],
})
if (process.env.NODE_ENV !== "production") globalForPrisma.prisma = prisma
Exemple d’utilisation dans une page SSR :
// src/app/page.tsx
import { prisma } from "@/lib/prisma"
export default async function HomePage() {
const annonces = await prisma.annonce.findMany()
return (
<div>
<h1>Annonces immobilières</h1>
<ul>
{annonces.map(a => (
<li key={a.id}>
{a.titre} – {a.prix} €
</li>
))}
</ul>
</div>
)
}
✅ SSR + ORM.
8. Ajouter TailwindCSS pour la mise en forme
Avec l’option --tailwind
lors de la création du projet, tout est prêt.
Exemple
export default function CardAnnonce({ titre, prix }: { titre: string; prix: number }) {
return (
<div className="border rounded-lg shadow p-4 hover:bg-gray-50">
<h2 className="text-xl font-semibold">{titre}</h2>
<p className="text-gray-600">{prix} €</p>
</div>
)
}
9. Authentification et gestion des rôles
Objectifs
- Comprendre le rôle de l’authentification dans une application web moderne.
- Savoir différencier l’authentification (qui suis-je ?) de l’autorisation (que puis-je faire ?).
- Concevoir un système de gestion des utilisateurs et des rôles, connecté à une base de données.
Les trois briques principales
Élément | Rôle dans l’application | Outil associé |
---|---|---|
Authentification | Vérifie l’identité d’un utilisateur (connexion) | NextAuth |
Persistance des utilisateurs | Stocke les comptes, mots de passe, sessions | Prisma + Base de données |
Autorisation / Rôles | Définit ce qu’un utilisateur peut faire | Application (middleware, logique métier) |
Organisation globale
L’objectif est de mettre en place un parcours utilisateur complet :
-
Inscription (sign up) :
- Un visiteur crée un compte (nom, email, mot de passe).
- Son mot de passe est chiffré avant stockage.
- Un rôle par défaut lui est attribué (ex. “USER”).
-
Connexion (login) :
- L’utilisateur saisit ses identifiants.
- Le système vérifie son email et son mot de passe dans la base.
- Une session (ou un jeton JWT) est créée et stockée.
-
Session active :
- L’application reconnaît l’utilisateur à chaque requête.
- Les pages peuvent afficher du contenu personnalisé.
-
Déconnexion (logout) :
- La session est supprimée côté serveur et client.
-
Autorisation / rôles :
-
Certains rôles (ex. “AGENT”) ont des droits supplémentaires :
- publier ou modifier des annonces ;
- gérer les utilisateurs.
-
D’autres (ex. “USER”) ne peuvent que consulter et poser des questions.
-
Le modèle de données à prévoir
-
Utilisateur (
User
)- Identifiant unique
- Email, mot de passe (haché)
- Nom, image, etc.
- Rôle (
USER
,AGENT
,ADMIN
)
-
Session (
Session
)- Jeton d’authentification (JWT)
- Date d’expiration
- Lien vers un utilisateur
Ce modèle est géré automatiquement par Prisma et NextAuth via un adaptateur.
Étapes à réaliser
-
Configurer le système d’authentification :
- Installer et connecter
NextAuth
à la base via Prisma. - Définir un provider d’authentification “email + mot de passe”.
- Installer et connecter
-
Créer les pages nécessaires :
- Formulaire d’inscription → enregistre un nouvel utilisateur.
- Formulaire de connexion → envoie les identifiants à NextAuth.
-
Mettre en place la logique de session :
- Vérifier qu’un utilisateur est connecté avant d’accéder à certaines pages.
- Afficher son nom ou son rôle dans la barre de navigation.
-
Introduire la notion de rôles :
- Ajouter un champ
role
dans le modèleUser
. -
Mettre en place une logique d’accès :
- Les utilisateurs “AGENT” peuvent créer ou modifier des annonces.
- Les “USER” ne peuvent que consulter.
- Ajouter un champ
-
Protéger les routes sensibles :
- Via un middleware ou via une vérification côté serveur.
- Rediriger les utilisateurs non autorisés vers une page d’erreur ou de connexion.
📚 Ressources utiles
Next.js Docs → https://nextjs.org/docs Prisma Docs → https://www.prisma.io/docs TailwindCSS → https://tailwindcss.com/docs Auth.js (NextAuth) → https://authjs.dev