Nouveau : Datasets open source gratuits disponibles !Decouvrir →
Intermediaire 25 min Next.js

Securiser une application Next.js

Pourquoi Securiser une application Next.js ?

La sécurité est un aspect crucial que tout développeur doit prendre en compte lors de la création d'applications, et cela vaut particulièrement pour les applications Next.js. En raison de sa nature moderne et réactive, Next.js apporte des défis supplémentaires à la sécurité. Dans ce tutoriel, nous allons explorer comment sécuriser une application Next.js en abordant les concepts fondamentaux, en réalisant un projet fil rouge complet et en identifiant les erreurs courantes.

Prerequis

Avant de commencer cette formation, assurez-vous que vous disposez des connaissances suivantes :

  • Connaissance approfondie de JavaScript ES6+
  • Compréhension des concepts React
  • Familiarité avec le gestionnaire de paquets npm/yarn
  • Connaissance de la structure d'un projet Next.js

Outils à installer :

  • Node.js (version recommandée : 14.0.0 ou supérieure)
  • npm (v6.0.0 ou supérieure)

Concepts fondamentaux

1. Authentification et Autorisation

L'authentification vérifie l'identité d'un utilisateur, tandis que l'autorisation détermine ce qu'un utilisateur peut faire une fois authentifié.

Schema mental :

+-------------------+
|   Authentification|
+---------+---------+
          |
          v
+---------+---------+
|   Autorisation  |
+-------------------+

Code fonctionnel :

// pages/api/auth/[...nextauth].js

import NextAuth from 'next-auth';
import Providers from 'next-auth/providers';

export default NextAuth({
  providers: [
    Providers.Email({
      server: process.env.EMAIL_SERVER,
      from: process.env.EMAIL_FROM,
    }),
  ],
  callbacks: {
    async signIn(user, account, profile) { 
      return true; 
    },
    async session(session, token) {
      session.user.id = token.sub;
      return session;
    }
  }
});

2. Middleware

Middleware est une fonction qui effectue des opérations avant ou après la requête est traitée par un composant.

Schema mental :

+-------------------+
|   Middleware        |
+---------+---------+
          |
          v
+---------+---------+
|   Composant       |
+-------------------+

Code fonctionnel :

// middleware.js

export function middleware(req, ev) {
  if (req.headers.authorization !== 'Bearer mySecretToken') {
    return Response.json({ message: 'Unauthorized' }, { status: 401 });
  }
  return NextResponse.next();
}

3. Sécurité des Cookies

Les cookies sont utilisés pour stocker des informations sur le navigateur de l'utilisateur. Il est important de les sécuriser en désactivant la transmission en clair et en définissant un chemin sécurisé.

Schema mental :

+-------------------+
|   Cookies         |
+---------+---------+
          |
          v
+---------+---------+
|   Sécurité        |
+-------------------+

Code fonctionnel :

// next.config.js

module.exports = {
  cookies: {
    secure: true,
    httpOnly: true,
    sameSite: 'strict',
  },
};

Mise en pratique : projet fil rouge

Nous allons créer un mini-projet complet et réaliste : une application Next.js pour gérer des tâches. Voici les étapes à suivre :

  1. Initialiser le projet
npx create-next-app task-manager
cd task-manager
  1. Créer la page d'accueil
// pages/index.js

import Head from 'next/head';

export default function Home() {
  return (
    <div>
      <Head>
        <title>Task Manager</title>
      </Head>
      <h1>Welcome to Task Manager</h1>
    </div>
  );
}
  1. Créer le composant de liste des tâches
// components/TaskList.js

import React from 'react';

const TaskList = ({ tasks }) => {
  return (
    <ul>
      {tasks.map(task => (
        <li key={task.id}>{task.title}</li>
      ))}
    </ul>
  );
};

export default TaskList;
  1. Créer le composant de création de tâches
// components/CreateTask.js

import React, { useState } from 'react';

const CreateTask = ({ onAdd }) => {
  const [title, setTitle] = useState('');

  const handleSubmit = e => {
    e.preventDefault();
    onAdd({ title });
    setTitle('');
  };

  return (
    <form onSubmit={handleSubmit}>
      <input type="text" value={title} onChange={e => setTitle(e.target.value)} />
      <button type="submit">Create Task</button>
    </form>
  );
};

export default CreateTask;
  1. Mettre en place le state des tâches
// pages/index.js

import Head from 'next/head';
import TaskList from '../components/TaskList';
import CreateTask from '../components/CreateTask';

export default function Home() {
  const [tasks, setTasks] = useState([]);

  const addTask = task => {
    setTasks([...tasks, { id: Date.now(), ...task }]);
  };

  return (
    <div>
      <Head>
        <title>Task Manager</title>
      </Head>
      <h1>Welcome to Task Manager</h1>
      <CreateTask onAdd={addTask} />
      <TaskList tasks={tasks} />
    </div>
  );
}
  1. Ajouter un middleware pour la protection des routes sensibles
// middleware.js

export function middleware(req, ev) {
  if (req.headers.authorization !== 'Bearer mySecretToken') {
    return Response.json({ message: 'Unauthorized' }, { status: 401 });
  }
  return NextResponse.next();
}

Erreurs frequentes et debugging

1. Erreur : Invariant failed: You should not use <Route> or outside a <Router> component.

Code incorrect :

// pages/_app.js

import '../styles/globals.css';
import { useEffect } from 'react';

function MyApp({ Component, pageProps }) {
  return (
    <>
      <Component {...pageProps} />
    </>
  );
}

export default MyApp;

Code correct :

// pages/_app.js

import '../styles/globals.css';
import { useEffect } from 'react';

function MyApp({ Component, pageProps }) {
  return (
    <>
      <Component {...pageProps} />
    </>
  );
}

export default MyApp;

2. Erreur : Error: Error parsing JSON - Unexpected end of JSON input

Code incorrect :

// pages/api/task.js

import { NextApiRequest, NextApiResponse } from 'next';

export default function handler(req: NextApiRequest, res: NextApiResponse) {
  const task = req.body;
  // Code pour ajouter la tâche
}

Code correct :

// pages/api/task.js

import { NextApiRequest, NextApiResponse } from 'next';

export default function handler(req: NextApiRequest, res: NextApiResponse) {
  if (req.method === 'POST') {
    const task = req.body;
    // Code pour ajouter la tâche
  } else {
    res.status(405).json({ message: 'Method not allowed' });
  }
}

3. Erreur : Error: connect ECONNREFUSED 127.0.0.1:3000

Code incorrect :

// pages/api/auth/[...nextauth].js

import NextAuth from 'next-auth';
import Providers from 'next-auth/providers';

export default NextAuth({
  providers: [
    Providers.Email({
      server: process.env.EMAIL_SERVER,
      from: process.env.EMAIL_FROM,
    }),
  ],
});

Code correct :

// pages/api/auth/[...nextauth].js

import NextAuth from 'next-auth';
import Providers from 'next-auth/providers';

export default NextAuth({
  providers: [
    Providers.Email({
      server: process.env.EMAIL_SERVER,
      from: process.env.EMAIL_FROM,
    }),
  ],
});

Pour aller plus loin

  1. Intégrer le stockage sécurisé des données avec Prisma
  2. Ajouter un système de notifications push
  3. Déployer l'application sur Vercel

Défi pratique : Ajoutez une fonctionnalité pour supprimer des tâches en utilisant une requête DELETE dans la route API correspondante.


Ce tutoriel a couvert les concepts fondamentaux de la sécurité d'une application Next.js et a montré comment les mettre en œuvre dans un projet réel. En suivant ces étapes, vous devriez être capable de sécuriser votre application contre les menaces courantes et de protéger vos utilisateurs.

Besoin d'aide sur Next.js ?

Besoin d'aide sur un projet technique ? Decrivez-le pour des conseils personnalises.

Recevoir des conseils

Questions frequentes

Quelles sont les meilleures pratiques pour sécuriser les routes API dans une application Next.js ?
Les meilleures pratiques pour sécuriser les routes API dans une application Next.js incluent l'utilisation de middlewares comme 'next-auth' ou 'firebase-admin', la validation des entrées des utilisateurs, et l'utilisation de HTTPS pour crypter les communications.
Comment gérer les sessions utilisateur en toute sécurité dans une application Next.js ?
Pour gérer les sessions utilisateur en toute sécurité dans une application Next.js, il est recommandé d'utiliser des bibliothèques comme 'next-auth' qui offre un système de gestion de sessions sécurisé et facile à utiliser. Il faut également vérifier régulièrement la validité et l'intégrité des tokens de session.
Quelles mesures prendre pour protéger contre les attaques XSS dans une application Next.js ?
Pour protéger contre les attaques XSS dans une application Next.js, il est crucial d'éviter le rendu direct des entrées utilisateurs sans nettoyage. Utilisez des composants React qui se protègent automatiquement comme
doit être évité. De plus, assurez-vous que votre application utilise un Content Security Policy (CSP) approprié.

Pages liees

Chaque semaine, le meilleur de la tech francaise

Tendances, salaires, outils et opportunites — directement dans votre boite mail.

Gratuit. Desabonnement en un clic. Pas de spam.