Use Cases

Comment construire un systeme d'authentification avec Claude Code (JWT et OAuth)

Comment construire un systeme d'authentification avec Claude Code (JWT et OAuth). Guide pratique avec exemples de code.

Avantages d’utiliser Claude Code pour construire des systemes d’authentification

L’authentification est une fonctionnalite directement liee a la securite, et les erreurs d’implementation peuvent entrainer des vulnerabilites graves. Claude Code peut generer des implementations basees sur les meilleures pratiques de securite et proposer des contre-mesures contre les vecteurs d’attaque souvent negliges.

Implementation de l’authentification JWT

> Implemente l'authentification JWT avec Express + TypeScript.
> Utilise un schema a 2 tokens : access token (15 min) et refresh token (7 jours).
> Gere le refresh token avec des cookies httpOnly.

Service d’authentification

import jwt from 'jsonwebtoken';
import bcrypt from 'bcrypt';
import { prisma } from './db';

const ACCESS_TOKEN_SECRET = process.env.ACCESS_TOKEN_SECRET!;
const REFRESH_TOKEN_SECRET = process.env.REFRESH_TOKEN_SECRET!;

interface TokenPayload {
  userId: string;
  email: string;
}

export class AuthService {
  async register(email: string, password: string, name: string) {
    const existing = await prisma.user.findUnique({ where: { email } });
    if (existing) throw new Error('Cet e-mail est deja enregistre');

    const hashedPassword = await bcrypt.hash(password, 12);
    const user = await prisma.user.create({
      data: { email, password: hashedPassword, name },
    });

    return this.generateTokens({ userId: user.id, email: user.email });
  }

  async login(email: string, password: string) {
    const user = await prisma.user.findUnique({ where: { email } });
    if (!user) throw new Error('Identifiants invalides');

    const valid = await bcrypt.compare(password, user.password);
    if (!valid) throw new Error('Identifiants invalides');

    return this.generateTokens({ userId: user.id, email: user.email });
  }

  async refreshToken(token: string) {
    const payload = jwt.verify(token, REFRESH_TOKEN_SECRET) as TokenPayload;

    // Verifier la validite du refresh token en BD
    const stored = await prisma.refreshToken.findFirst({
      where: { token, userId: payload.userId, revoked: false },
    });
    if (!stored) throw new Error('Refresh token invalide');

    // Invalider l'ancien token (rotation des tokens)
    await prisma.refreshToken.update({
      where: { id: stored.id },
      data: { revoked: true },
    });

    return this.generateTokens(payload);
  }

  private async generateTokens(payload: TokenPayload) {
    const accessToken = jwt.sign(payload, ACCESS_TOKEN_SECRET, {
      expiresIn: '15m',
    });
    const refreshToken = jwt.sign(payload, REFRESH_TOKEN_SECRET, {
      expiresIn: '7d',
    });

    await prisma.refreshToken.create({
      data: { token: refreshToken, userId: payload.userId },
    });

    return { accessToken, refreshToken };
  }
}

Middleware d’authentification

import { Request, Response, NextFunction } from 'express';
import jwt from 'jsonwebtoken';

export function authMiddleware(req: Request, res: Response, next: NextFunction) {
  const header = req.headers.authorization;
  if (!header?.startsWith('Bearer ')) {
    return res.status(401).json({ error: 'Token non fourni' });
  }

  const token = header.slice(7);

  try {
    const payload = jwt.verify(token, process.env.ACCESS_TOKEN_SECRET!);
    req.user = payload as TokenPayload;
    next();
  } catch (err) {
    return res.status(401).json({ error: 'Token invalide ou expire' });
  }
}

Configuration du routeur

import { Router } from 'express';
import { AuthService } from './auth-service';

const router = Router();
const auth = new AuthService();

router.post('/register', async (req, res) => {
  try {
    const { accessToken, refreshToken } = await auth.register(
      req.body.email, req.body.password, req.body.name
    );
    res.cookie('refreshToken', refreshToken, {
      httpOnly: true,
      secure: true,
      sameSite: 'strict',
      maxAge: 7 * 24 * 60 * 60 * 1000,
    });
    res.json({ accessToken });
  } catch (err) {
    res.status(400).json({ error: (err as Error).message });
  }
});

router.post('/login', async (req, res) => {
  try {
    const { accessToken, refreshToken } = await auth.login(
      req.body.email, req.body.password
    );
    res.cookie('refreshToken', refreshToken, {
      httpOnly: true,
      secure: true,
      sameSite: 'strict',
      maxAge: 7 * 24 * 60 * 60 * 1000,
    });
    res.json({ accessToken });
  } catch (err) {
    res.status(401).json({ error: 'Identifiants invalides' });
  }
});

router.post('/refresh', async (req, res) => {
  try {
    const token = req.cookies.refreshToken;
    const { accessToken, refreshToken } = await auth.refreshToken(token);
    res.cookie('refreshToken', refreshToken, {
      httpOnly: true,
      secure: true,
      sameSite: 'strict',
      maxAge: 7 * 24 * 60 * 60 * 1000,
    });
    res.json({ accessToken });
  } catch (err) {
    res.status(401).json({ error: 'Refresh token invalide' });
  }
});

export default router;

Integration OAuth (Google)

> Ajoute la connexion Google avec PassportJS. Integre-le avec l'authentification JWT existante.
import passport from 'passport';
import { Strategy as GoogleStrategy } from 'passport-google-oauth20';

passport.use(new GoogleStrategy({
  clientID: process.env.GOOGLE_CLIENT_ID!,
  clientSecret: process.env.GOOGLE_CLIENT_SECRET!,
  callbackURL: '/auth/google/callback',
}, async (accessToken, refreshToken, profile, done) => {
  let user = await prisma.user.findFirst({
    where: { providerId: profile.id, provider: 'google' },
  });

  if (!user) {
    user = await prisma.user.create({
      data: {
        email: profile.emails![0].value,
        name: profile.displayName,
        provider: 'google',
        providerId: profile.id,
      },
    });
  }

  done(null, user);
}));

Liste de verification de securite

Vous pouvez demander a Claude Code un audit de securite avec le prompt suivant.

> Passe en revue le code d'authentification du point de vue de la securite.
> Verifie selon le OWASP Top 10.

Les principaux points de verification sont :

  • bcrypt est utilise pour le hachage des mots de passe
  • La cle secrete JWT est suffisamment longue
  • La rotation des refresh tokens est implementee
  • Des mesures anti-CSRF sont appliquees
  • Le rate limiting est configure

Pour maintenir la qualite du code y compris la securite, l’automatisation du refactoring est egalement efficace. De plus, si vous documentez les politiques de configuration d’authentification dans CLAUDE.md, Claude Code generera du code coherent.

Summary

Avec Claude Code, vous pouvez construire efficacement un systeme d’authentification robuste incluant l’authentification JWT et l’integration OAuth. En generant du code base sur les meilleures pratiques de securite, il est plus facile d’adresser les vulnerabilites souvent negligees. Assurez-vous de gerer les cles secretes de maniere securisee et d’utiliser la communication HTTPS en environnement de production.

Pour plus de details, consultez la documentation officielle d’Anthropic.

#Claude Code #authentication #JWT #OAuth #security