39-2 Décoder le jeton pour utiliser son contenu
Dans l'en-tête du site, les informations de connexion proviennent de la propriété pseudo du localstorage et non des informations contenues dans le jeton.
Pour obtenir ces informations, il faut décoder le jeton.
Modifier le modèle utilisateur
Modifions le modèle utilisateur pour qu'il contienne les informations nécessaires en provenance du jeton. Dans mon cas, je ne retourne que l'identifiant, le courriel et le nom d'utilisateur.
export interface Utilisateur {
id: number;
courriel: string;
nomUtilisateur: string;
}
Installer jwt-decode
La librairie jwt-decode peut nous aider à gérer tout ce qui a trait au traitement du jeton côté client. Entre autres, décoder le jeton et obtenir les informations qu'il contient. Sans cette librairie, il faudrait manuellement décortiquer les trois sections du jeton, convertir de base64 au format texte, extraire l'objet JSON du contenu, etc.
- Installez la librairie via
npm
npm install jwt-decode
Décoder le jeton dans AuthService
La dernière étape consiste à décoder le jeton afin d'en récupérer son contenu. AuthService est déjà responsable de retourner un utilisateur via sa fonction obtenirUtilisateur(), alors modifions cette dernière pour qu'elle retourne l'utilisateur contenu dans le jeton.
-
Créer un modèle idem à celui retourné du serveur, soit
JwtPayloadpour représenter le contenu du jeton.src/app/core/models/jwt-payload.tsexport interface JwtPayload {
sub: number;
courriel: string;
nomUtilisateur: string;
} -
Décoder le jeton et retourner un utilisateur
src/app/core/services/auth-service.tsobtenirUtilisateur(): Utilisateur | null {
const token = localStorage.getItem('access_token');
if(token){
const jwtPayload = jwtDecode<JwtPayload>(token);
if(jwtPayload){
let utilisateur: Utilisateur = {
id: jwtPayload.sub,
courriel: jwtPayload.courriel,
nomUtilisateur: jwtPayload.nomUtilisateur,
}
return utilisateur
}
}
return null;
}infojwtDecode<JwtPayload>(token)décode le jeton dans le localstorage et retourne son contenu sous la forme de notre modèleJwtPayload. -
Vérifier si le jeton est expiré. Il faut en effet vérifier si le jeton n'est plus valide. Pour cela, créer une fonction
tokenIsExpired.src/app/core/services/auth-service.tsprivate tokenIsExpired(token: string) {
try {
const decoded: any = jwtDecode(token);
if (!decoded.exp) {
return false; // Pas de date d'expiration, donc pas expiré
}
// exp est en secondes, Date.now() en millisecondes
const currentTime = Date.now() / 1000;
return decoded.exp < currentTime;
} catch (error) {
return false; // Si le jeton est invalide, le traiter comme expiré
}
} -
Tenir compte de la date d'expiration dans
obtenirUtilisateur()obtenirUtilisateur(): Utilisateur | null {
const token = localStorage.getItem('access_token');
if(token && !this.tokenIsExpired(token)) {
try {
//... -
On peut en profiter d'ailleurs pour modifier la fonction
estConnecte()permettant de vérifier si un utilisateur est connecté à l'application ou non.src/app/services/auth.service.tsestConnecte() {
return this.obtenirUtilisateur() !== null
}infoLa fonction obtenir utilisateur vérifie l'expiration du jeton, donc nous avons seulement à vérifier si la fonction ne retourne PAS
null.
Afficher le nom d'utilisateur ou autre info pertinente
Cela nous permet maintenant d'utiliser le même principe que précédemment afin de récupérer les informations de l'utilisateur et les afficher.
Par exemple, pour afficher le nom d'utilisateur plutôt que le pseudo dans la barre de navigation:
<ul *ngIf="utilisateur" class="navbar-nav">
<li>Allô, {{utilisateur.nomUtilisateur}}!</li>
</ul>
