Génération et Manipulation des Jetons JWT avec SimpleJWT dans Django

Dans l'écosystème de Django REST Framework, la bibliothèque SimpleJWT fournit la classe AccessToken pour représenter la composante d'accès d'un JSON Web Token (JWT). Ce jeton est fondamental pour sécuriser les points de terminaison d'une API en transportant des informations d'authentificaiton, des permissions et une durée de validité.

La classe AccessToken offre trois fonctionnalités principales :

  • Génération : Elle permet d'émettre de nouveaux jetons via des méthodes comme for_user (pour un utilisateur spécifique) ou d'instancier un objet à partir d'une chaîne existante.
  • Décodage : La méthode decode transforme une chaîne JWT en objet AccessToken, facilitant l'extraction des données de la charge utile (payload).
  • Validation : Des méthodes intégrées telles que verify et verify_exp garantissent l'intégrité du jeton et vérifient qu'il n'a pas expiré ou été altéré.

Création de jetons avec for_user

La méthode de classe AccessToken.for_user est conçue pour générer un jeton d'accès lié à une instance du modèle utilisateur de Django. Elle encapsule les informations d'identification et les métadonnées de session dans la charge utile du JWT.

Voici une implémentation modifiée illustrant son utilisation :

from django.contrib.auth import get_user_model
from rest_framework_simplejwt.tokens import AccessToken

UserModel = get_user_model()

# Récupération de l'utilisateur cible
target_account = UserModel.objects.get(email='admin@example.com')

# Instanciation du jeton d'accès
token_instance = AccessToken.for_user(target_account)

# Sérialisation en chaîne de caractères pour la transmission
encoded_token = str(token_instance)

Dans ce scénario, token_instance est un objet Python riche qui peut être manipulé avant d'être converti en chaîne via la fonction native str().

Génération rapide avec get_token

Pour les cas où la manipulation de l'objet token n'est pas nécessaire, SimpleJWT propose la fonction utilitaire get_token. Cette fonction prend directement une instance utilisateur et retourne la chaîne JWT encodée, contournant ainsi l'étape de conversion manuelle.

Exemple d'implémentation :

from django.contrib.auth import get_user_model
from rest_framework_simplejwt.tokens import get_token

UserModel = get_user_model()

# Identification de l'utilisateur
target_account = UserModel.objects.get(email='admin@example.com')

# Obtention directe de la chaîne JWT
raw_jwt_string = get_token(target_account)

Ici, raw_jwt_string est immédiatement prêt à être envoyé au client, ce qui rend le code plus concis lorsque seule la valeur textuelle du jeton est requise.

Intégration avec les Sérialiseurs

Lors de l'authentification via des identifiants bruts, il est courant de combiner la validation des données avec la génération du jeton. Bien que get_token soit pratique, on peut également passer par le sérialiseur standadr :

from rest_framework_simplejwt.serializers import TokenObtainPairSerializer
from rest_framework_simplejwt.tokens import AccessToken

credentials = {
    'username': 'admin_user',
    'password': 'secure_password_123'
}

# Validation des identifiants
auth_serializer = TokenObtainPairSerializer(data=credentials)
auth_serializer.is_valid(raise_exception=True)

# Extraction de l'utilisateur validé et génération du jeton
authenticated_user = auth_serializer.validated_data['user']
custom_token = AccessToken.for_user(authenticated_user)
final_jwt = str(custom_token)

Comparaison et Cas d'Usage

Le choix entre AccessToken.for_user et get_token dépend principalement du niveau de contrôle requis sur le jeton :

  • AccessToken.for_user retourne un objet AccessToken. C'est l'approche privilégiée si vous devez modifier la charge utile (ajouter des claims personnalisés), inspecter la date d'expiration ou ajuster les scopes avant la sérialisation.
  • get_token retourne directement une chaîne de caractères. C'est la solution optimale pour une génération rapide et simple, lorsque le jeton standard suffit et qu'aucune altération de l'objet n'est prévue.
from django.contrib.auth import get_user_model
from rest_framework_simplejwt.tokens import AccessToken, get_token

UserModel = get_user_model()
account = UserModel.objects.get(username='test_user')

# Approche orientée objet
obj_token = AccessToken.for_user(account)
str_from_obj = str(obj_token)

# Approche fonctionnelle directe
str_from_func = get_token(account)

# Les deux chaînes produites sont fonctionnellement équivalentes
assert str_from_obj == str_from_func

Étiquettes: Django djangorestframework simplejwt jsonwebtoken Python

Publié le 28 juin à 00h21