Aller au contenu principal

38-1 Configuration de la stratégie d'authentification (JWT Strategy)

Pour récupérer le jeton automatiquement, ainsi que l'utilisateur associé, on utilise le concept de stratégie dans la librairie Passport.

Une stratégie au sens Passport est un moyen d'authentifier un utilisateur. Une de ces stratégies est l'authentification via jeton JWT. C'est cette dernière que nous utiliserons puisque notre mécanisme d'authentification est basé sur ce type de jeton.

Créer la stratégie d'interception et d'authentification

On créera un fichier src/auth/jwt.strategy.ts qui sera responsable de récupérer le jeton et d'obtenir l'utilisateur associé.

  1. Créer un fichier jwt.strategy.ts sous src/auth
src/auth/jwt.strategy.ts
import { PassportStrategy } from '@nestjs/passport';
import { Strategy } from 'passport-jwt';

export class JwtStrategy extends PassportStrategy(Strategy){
}
info

Importez Strategy de passport-jwt. Imgur

À noter que notre classe hérite de PassportStrategy(Strategy), c'est ce qui donnera les capacités à cette classe de récupérer un jeton JWT et d'en faire le traitement.

  1. Via le constructeur, spécifier la stratégie pour récupérer le jeton. On utilise un jeton inclus dans l'en-tête (Bearer Token) et c'est donc la fonction fromAuthHeaderAsBearerToken qui sera utilisée.
src/auth/jwt.strategy.ts
export class JwtStrategy extends PassportStrategy(Strategy){
constructor(){
super({
jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(),
});
}
}
info

Vous aurez une erreur, c'est normal!

  1. Spécifier si on ignore ou non l'expiration du jeton (date d'expiration), ce que nous ne voulons pas ignorer.
src/auth/jwt.strategy.ts
export class JwtStrategy extends PassportStrategy(Strategy){
constructor(){
super({
jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(),
ignoreExpiration: false,
});
}
}
  1. Finalement, spécifiez la clé secrète à utiliser pour valider le jeton.
src/auth/jwt.strategy.ts
export class JwtStrategy extends PassportStrategy(Strategy){
constructor(){
super({
jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(),
ignoreExpiration: false,
secretOrKey: process.env.JWT_SECRET!,

})
}
}
info

Vous devriez déjà avoir une entrée JWT_SECRET dans votre fichier .env pour la clé secrète.

Valider et récupérer le contenu du jeton

Pour valider le contenu du jeton, Passport appellera la fonction validate de notre classe, avec le jeton en paramètre.

  1. Passport décodera le jeton et nous le retournera sous forme décodée. Créons un DTO (sous le dossier auth/dto) représentant le contenu décodé du jeton JWT:
    src/auth/dto/jwt-payload.dto.ts
    export class JwtPayloadDto {
    sub: number;
    courriel: string;
    nomUtilisateur: string;
    }
  2. Dans la classe JwtStrategy, créer la fonction validate, acceptant un jeton en entrée et retournant un utilisateur. Cette fonction permettra de vérifier que les informations de l'utilisateur contenues dans le jeton correspondent à un utilisateur valide dans votre base de données.
    src/auth/jwt.strategy.ts
    async validate(payload: JwtPayloadDto): Promise<Utilisateur> {

    }
  3. En effectuant une requête à la base de données, trouver l'utilisateur à partir de l'identifiant désiré, soit celui contenu dans le jeton (ex.: courriel).
    src/auth/jwt.strategy.ts
    async validate(payload: JwtPayloadDto): Promise<Utilisateur> {
    const utilisateur = await Utilisateur.findOne({
    where: {
    courriel: payload.courriel.toLowerCase(),
    },
    });
    }
  4. Retourner soit une erreur d'autorisation ou l'utilisateur, tout dépendant de si un utilisateur a été trouvé ou non.
    src/auth/jwt.strategy.ts
    async validate(payload: JwtPayloadDto): Promise<Utilisateur> {
    const utilisateur = await Utilisateur.findOne({
    where: {
    courriel: payload.courriel.toLowerCase(),
    },
    });

    if (!utilisateur) {
    throw new UnauthorizedException();
    }

    return utilisateur;
    }

Ajouter JwtStrategy en tant que provider du module Auth

Finalement, ajoutez JwtStrategy comme provider dans le module d'authentification. Le concept de provider est simplement qu'ils peuvent être utilisés par le mécanisme d'injection de dépendance de Nest.

src/auth/auth.module.ts
//...
providers: [AuthService, JwtStrategy],
//...