Middleware Hono : protéger tes routes privées en tokens
Implémente un middleware Hono en TypeScript pour vérifier JWT et cookie, sécuriser chaque route privée et isoler ta logique métier. Apprends les tests clés.
Pourquoi ajouter un middleware d’authentification
Une API publique n’a pas besoin de filtre.
Dès que tu exposes des routes privées, tu dois valider l’identité du client avant d’exécuter
ta logique metier.
Avec Hono, la bonne pratique consiste à encapsuler cette vérification dans
un middleware réutilisable.
Avantages immédiats :
- Code DRY : une seule fonction protège toutes les routes.
- Lisibilité : ton handler focus sur la logique métier, pas sur la sécurité.
- Testabilité : le middleware s’isole et se teste unitairement.
Rappel : d’où vient le token ?
Le mini-cours a déjà créé :
- Un endpoint de connexion qui renvoie un JWT.
- Un utilitaire
setAuthCookie()qui stocke le token dans un cookieHttpOnly; Secure.
Le client peut ensuite :
- envoyer le token dans l’en-tête
Authorization: Bearer <token>; - ou laisser le navigateur renvoyer le cookie automatiquement.
Le middleware authenticateUserMiddleware
1import { createMiddleware } from "hono/factory";2import { HTTPException } from "hono/http-exception";3import { getExistingToken } from "../token.js";4import { getAuthToken } from "../utils/cookie-utils.js";56export const authenticateUserMiddleware = createMiddleware(async (c, next) => {7const authorizationHeader = c.req.header("Authorization");8const cookieToken = getAuthToken(c);910let token: string | undefined;1112if (authorizationHeader) {13token = authorizationHeader.split(" ")[1];14} else if (cookieToken) {15token = cookieToken;16}1718if (!token) {19throw new HTTPException(401, {20message: "You are not authorized to access this resource",21});22}2324const existingToken = await getExistingToken({ token });2526if (!existingToken) {27throw new HTTPException(401, {28message: "You are not authorized to access this resource",29});30}3132c.set("user", existingToken.user);3334await next();35});
Explications pas à pas :
-
createMiddleware
La fabrique Hono reçoit ta fonction(c, next)et la branche avant le handler ciblé. -
Recherche du token
- Priorité à l’en-tête
Authorization(utile pour les clients mobiles ou Postman). - Fallback sur le cookie, plus pratique côté navigateur.
- Priorité à l’en-tête
-
Absence de token
On lève uneHTTPException(401)directement.
Pourquoi ? On évite d’atteindre le handler, on économise des cycles CPU. -
Validation du token
getExistingToken()interroge la base via Prisma.
Si le token n’existe plus (logout, expiration manuelle, etc.), on renvoie 401. -
Hydratation du contexte
c.set("user", existingToken.user)ajoute l’utilisateur courant au contexte Hono.
Les handlers en aval y accèdent viac.get("user"). -
await next()
On passe la main seulement si toutes les vérifs sont OK.
Brancher le middleware sur tes routes
1import { Hono } from "hono";2import { authenticateUserMiddleware } from "../middlewares/authenticateUser.ts";34const privateRoutes = new Hono();56// applique le middleware a toutes les routes du groupe7privateRoutes.use("*", authenticateUserMiddleware);89privateRoutes.get("/profile", (c) => {10const user = c.get("user");11return c.json({ id: user.id, email: user.email });12});1314export default privateRoutes;
Pourquoi use("*", middleware) ?
Tu assures que toute requête vers ce groupe passe par la vérification d’auth.
Cas d’erreur à tester
1--- Terminal2curl -i localhost:8787/profile3--- Result4HTTP/1.1 401 Unauthorized5{ "error": "You are not authorized to access this resource" }
- Sans token : 401 direct.
- Avec token invalide : 401.
- Avec token valide : 200 et le JSON du profil.
Aller plus loin
- Chiffrer le token JWT à l’aide d’un secret robuste.
- Implémenter une date d’expiration et un refresh token.
- Logger les tentatives d’accès refusées (monitoring).
Important
Le middleware est central : toute faille ici compromet l’ensemble de l’API. Relis bien le code et écris des tests unitaires ciblés.
Conclusion
Tu viens d’ajouter une barrière de sécurité simple et efficace.
Grâce à ce middleware, chaque route privée vérifie la présence et la validité du token avant
d’exécuter la moindre ligne de logique métier.
Étape suivante du mini-cours : valider les payloads utilisateurs avec Zod.
Quiz
Testez vos connaissances avec 5 questions
Pourquoi encapsuler la vérification du token dans un middleware Hono plutôt que de la faire dans chaque handler ?
Dans quel ordre le middleware "authenticateUserMiddleware" recherche-t-il un token ?
Quelle réponse HTTP est renvoyée lorsque le middleware ne trouve aucun token ou détecte un token invalide ?
Quel est l’effet de l’appel c.set("user", existingToken.user) dans le middleware ?
Pourquoi le middleware appelle-t-il await next() uniquement après avoir passé toutes les vérifications ?