# Guide Final : Auth avec Custom User, Djoser et Simple JWT

Ce document présente l'approche **recommandée et la plus robuste** pour mettre en place l'authentification dans un nouveau projet Django. Elle est basée sur trois piliers :

1.  **Custom User Model** : Pour une flexibilité maximale à long terme.
2.  **Djoser** : Pour des endpoints d'authentification et de gestion utilisateur complets et sécurisés.
3.  **Simple JWT** : Pour la gestion des JSON Web Tokens.

---

## AVERTISSEMENT CRUCIAL : À FAIRE AU DÉBUT DU PROJET

La mise en place d'un **Custom User Model** doit impérativement être la **toute première chose** que vous faites après avoir créé votre projet Django. 

Vous devez effectuer ces étapes **AVANT** de lancer la commande `python manage.py migrate` pour la première fois. Si vous avez déjà une base de données avec des migrations, vous devrez la supprimer et recommencer.

---

## Étape 1 : Création de l'application et du modèle `CustomUser`

Nous allons créer une application dédiée à la gestion des utilisateurs.

1.  **Créez une nouvelle application `users`** :
    ```bash
    python manage.py startapp users
    ```

2.  **Définissez votre `CustomUser` dans `users/models.py`**.
    Nous héritons de `AbstractUser` pour conserver tous les champs et fonctionnalités du `User` de base, tout en nous gardant la possibilité d'en ajouter d'autres plus tard.

    ```python
    # users/models.py
    from django.contrib.auth.models import AbstractUser
    from django.db import models

    class CustomUser(AbstractUser):
        # Vous pouvez ajouter des champs supplémentaires ici à l'avenir
        # par exemple :
        # bio = models.TextField(blank=True)
        # avatar = models.ImageField(upload_to='avatars/', null=True, blank=True)
        pass

    def __str__(self):
        return self.username
    ```

3.  **Enregistrez ce modèle dans l'interface d'administration** (`users/admin.py`) :

    ```python
    # users/admin.py
    from django.contrib import admin
    from django.contrib.auth.admin import UserAdmin
    from .models import CustomUser

    class CustomUserAdmin(UserAdmin):
        model = CustomUser
        # Personnalisez les champs affichés dans l'admin si nécessaire
        # list_display = ['email', 'username', 'is_staff']

    admin.site.register(CustomUser, CustomUserAdmin)
    ```

## Étape 2 : Configuration de `settings.py`

1.  **Ajoutez votre nouvelle application `users` à `INSTALLED_APPS`**. Assurez-vous qu'elle est listée avec les autres applications (`rest_framework`, `djoser`).

    ```python
    INSTALLED_APPS = [
        # ...
        'rest_framework',
        'djoser',
        'users', # Notre nouvelle application
        # ...
    ]
    ```

2.  **Indiquez à Django d'utiliser votre modèle**.
    C'est la ligne la plus importante de ce guide. Ajoutez-la n'importe où dans `settings.py`.

    ```python
    AUTH_USER_MODEL = 'users.CustomUser'
    ```

3.  **Configurez `REST_FRAMEWORK` et `SIMPLE_JWT`** (identique aux guides précédents).

    ```python
    REST_FRAMEWORK = {
        'DEFAULT_AUTHENTICATION_CLASSES': (
            'rest_framework_simplejwt.authentication.JWTAuthentication',
        ),
        'DEFAULT_PERMISSION_CLASSES': (
            'rest_framework.permissions.IsAuthenticated',
        )
    }

    from datetime import timedelta
    SIMPLE_JWT = {
        "ACCESS_TOKEN_LIFETIME": timedelta(minutes=5),
        "REFRESH_TOKEN_LIFETIME": timedelta(days=1),
    }
    ```

4.  **Configurez `DJOSER` pour qu'il utilise vos modèles et serializers**.
    Nous devons explicitement dire à Djoser où trouver les serializers pour notre `CustomUser` (que nous allons créer à l'étape suivante).

    ```python
    DJOSER = {
        'PASSWORD_RESET_CONFIRM_URL': '#/password/reset/confirm/{uid}/{token}',
        'USERNAME_RESET_CONFIRM_URL': '#/username/reset/confirm/{uid}/{token}',
        'ACTIVATION_URL': '#/activate/{uid}/{token}',
        'SEND_ACTIVATION_EMAIL': False,
        'USER_CREATE_PASSWORD_RETYPE': True,
        'PASSWORD_RESET_SHOW_EMAIL_NOT_FOUND': True,
        # Pointer vers nos serializers personnalisés
        'SERIALIZERS': {
            'user_create': 'users.serializers.UserCreateSerializer',
            'user': 'users.serializers.UserSerializer',
            'current_user': 'users.serializers.UserSerializer',
        },
    }
    ```

## Étape 3 : Création des Serializers Personnalisés

Créez un nouveau fichier `users/serializers.py`.

```python
# users/serializers.py
from djoser.serializers import UserCreateSerializer as BaseUserCreateSerializer
from djoser.serializers import UserSerializer as BaseUserSerializer
from .models import CustomUser

class UserCreateSerializer(BaseUserCreateSerializer):
    class Meta(BaseUserCreateSerializer.Meta):
        model = CustomUser
        fields = ('id', 'username', 'email', 'password')

class UserSerializer(BaseUserSerializer):
    class Meta(BaseUserSerializer.Meta):
        model = CustomUser
        fields = ('id', 'username', 'email') # Ne jamais exposer le mot de passe ici
```

## Étape 4 : Configuration des URLs

Cette étape reste inchangée par rapport au guide Djoser précédent. Djoser est assez intelligent pour utiliser votre `CustomUser` grâce à la configuration.

Dans votre `core/urls.py` :
```python
from django.contrib import admin
from django.urls import path, include

urlpatterns = [
    path('admin/', admin.site.urls),
    path('auth/', include('djoser.urls')),
    path('auth/', include('djoser.urls.jwt')),
]
```

## Étape 5 : Lancement des Migrations (Ordre Crucial)

Maintenant que tout est configuré, vous pouvez créer et appliquer vos migrations en toute sécurité.

1.  **Créez la migration pour votre application `users`** :
    ```bash
    python manage.py makemigrations users
    ```
    *Vous devriez voir un message indiquant que la migration pour le modèle `CustomUser` a été créée.*

2.  **Appliquez toutes les migrations** :
    ```bash
    python manage.py migrate
    ```
    *Django va maintenant créer toutes ses tables internes (auth, admin, sessions) en utilisant votre `users.CustomUser` comme référence pour l'utilisateur.*

## Conclusion

Félicitations ! Vous disposez maintenant d'un système d'authentification complet, riche en fonctionnalités, et surtout, bâti sur une fondation flexible qui pourra évoluer avec votre projet. C'est l'approche standard pour les projets Django professionnels et robustes.
