89 votes

Authentification par jeton du cadre Django Rest

J'ai lu les guides du cadre de repos Django et suivi tous les tutoriels. Tout semble avoir un sens et fonctionner comme il se doit. J'ai réussi à faire fonctionner l'authentification de base et de session comme décrit.

django rest framework - guide api

Cependant, j'ai du mal avec la partie de la documentation relative à l'authentification par jeton, elle manque un peu ou n'est pas aussi approfondie que les tutoriels.

django-rest-framework - authentification par jetons

Il est indiqué que je dois créer des jetons pour les utilisateurs mais il est précisé où dans models.py ?

Quelqu'un peut-il expliquer un peu mieux la partie de la documentation relative à l'authentification par jeton pour un débutant ?

94voto

Cheng Points 5906

@ian-clelland a déjà fourni la bonne réponse. Il y a juste quelques petits détails qui n'ont pas été mentionnés dans son message, donc je vais documenter les procédures complètes (j'utilise Django 1.8.5 et DRF 3.2.4) :

  1. Faites les choses suivantes AVANT vous créez le super-utilisateur. Sinon, le superutilisateur n'aura pas son jeton créé.

  2. Aller à paramètres.py et ajoutez ce qui suit :

    INSTALLED_APPS = (
        'rest_framework',
        'rest_framework.authtoken',
        'myapp',
    )
    
    REST_FRAMEWORK = {
        'DEFAULT_PERMISSION_CLASSES': (
            'rest_framework.permissions.IsAuthenticated',
        ),
        'DEFAULT_AUTHENTICATION_CLASSES': (
            'rest_framework.authentication.TokenAuthentication',
        )
    }
  3. Ajoutez le code suivant dans myapp 's models.py :

    from django.db.models.signals import post_save
    from django.dispatch import receiver
    from rest_framework.authtoken.models import Token
    from django.conf import settings
    
    # This code is triggered whenever a new user has been created and saved to the database
    @receiver(post_save, sender=settings.AUTH_USER_MODEL)
    def create_auth_token(sender, instance=None, created=False, **kwargs):
        if created:
            Token.objects.create(user=instance)

    Alternativement, si vous voulez être plus explicite, créez un fichier nommé signaux.py sous myapp projet. Mettez-y le code ci-dessus, puis dans __init__.py , écrivez import signals

  4. Ouvrez une fenêtre de console, naviguez dans le répertoire de votre projet, et entrez la commande suivante :

    python manage.py migrate
    python manage.py makemigrations

    Regardez dans votre base de données, une table nommée authtoken_token doit être créé avec les champs suivants : key (la valeur du jeton), created (la date de création), user_id (une clé étrangère qui fait référence à la colonne id de la table auth_user).

  5. créer un superutilisateur avec python manage.py createsuperuser . Maintenant, jetez un coup d'œil à la authtoken_token dans votre BD avec select * from authtoken_token; vous devriez voir qu'une nouvelle entrée a été ajoutée.

  6. Utilisation de curl ou une alternative beaucoup plus simple httpie pour tester l'accès à votre api, j'utilise httpie :

    http GET 127.0.0.1:8000/whatever 'Authorization: Token your_token_value'

    C'est ça. À partir de maintenant, pour tout accès à l'API, vous devez inclure la valeur suivante dans l'en-tête HTTP ( faites attention aux espaces blancs ) :

    Authorization: Token your_token_value
  7. (Facultatif) La DRF permet également de renvoyer le jeton d'un utilisateur si vous fournissez le nom d'utilisateur et le mot de passe. Tout ce que vous avez à faire est d'inclure ce qui suit dans le fichier urls.py :

    from rest_framework.authtoken import views
    
    urlpatterns = [
        ...
        url(r'^api-token-auth/', views.obtain_auth_token),
    ]

    Utilisation de httpie pour vérifier :

    http POST 127.0.0.1:8000/api-token-auth/ username='admin' password='whatever'

    Dans le corps du retour, vous devriez voir ceci :

    {
        "token": "blah_blah_blah"
    }

C'est ça !

75voto

Ian Clelland Points 15066

Non, pas dans votre models.py -- du côté des modèles, tout ce que vous devez faire est d'inclure l'application appropriée ( rest_framework.authtoken ) dans votre INSTALLED_APPS . Cela fournira un modèle de jeton qui est une clé étrangère à l'utilisateur.

Ce que vous devez faire, c'est décider quand et comment ces objets à jeton doivent être créés. Dans votre application, chaque utilisateur reçoit-il automatiquement un jeton ? Ou seulement certains utilisateurs autorisés ? Ou seulement lorsqu'ils en font la demande expresse ?

Si chaque utilisateur doit toujours avoir un jeton, il y a un bout de code sur la page que vous avez indiquée qui vous montre comment configurer un signal pour les créer automatiquement :

@receiver(post_save, sender=User)
def create_auth_token(sender, instance=None, created=False, **kwargs):
    if created:
        Token.objects.create(user=instance)

(mettre ce dans un fichier models.py, n'importe où, et il sera enregistré lorsqu'un fil Django démarrera)

Si les jetons ne doivent être créés qu'à certains moments, alors dans votre code de vue, vous devez créer et enregistrer le jeton au moment approprié :

# View Pseudocode
from rest_framework.authtoken.models import Token

def token_request(request):
    if user_requested_token() and token_request_is_warranted():
        new_token = Token.objects.create(user=request.user)

Une fois le jeton créé (et enregistré), il sera utilisable pour l'authentification.

19voto

Super S Points 191

Sur Django 1.8.2 et rest framework 3.3.2, suivre toutes les étapes ci-dessus n'est pas suffisant pour activer l'authentification par jeton.

Bien que le paramètre REST_FRAMEWORK soit spécifié dans le fichier de paramètres de django, les vues basées sur des fonctions nécessitent le décorateur @api_view :

from rest_framework.decorators import api_view

@api_view(['POST','GET'])
def my_view(request):
    if request.user.is_authenticated():
       ...

Sinon, aucune authentification par jeton n'est effectuée.

16voto

parsenz Points 409

Pour ajouter mon grain de sel, si vous avez un gestionnaire d'utilisateurs personnalisé qui gère la création (et l'activation) des utilisateurs, vous pouvez également effectuer cette tâche comme suit :

from rest_framework.authtoken.models import Token
# Other imports

class UserManager(BaseUserManager):

    def create_user(self, **kwargs):
        """
        This is your custom method for creating user instances. 
        IMHO, if you're going to do this, you might as well use a signal.

        """
        # user = self.model(**kwargs) ...
        Token.objects.create(user=user)

    #You may also choose to handle this upon user activation. 
    #Again, a signal works as well here.

    def activate_user(**kwargs):
        # user = ...
        Token.objects.create(user=user)

Si vous avez déjà créé des utilisateurs, vous pouvez vous rendre dans le shell python de votre terminal et créer des Tokens pour tous les utilisateurs de votre base de données.

>>> from django.contrib.auth.models import User
>>> from rest_framework.authtoken.models import Token 
>>> for user in User.objects.all():
>>> ...    Token.objects.create(user=user)

J'espère que cela vous aidera.

10voto

Il existe un moyen plus propre d'obtenir le jeton d'utilisateur.

Exécutez simplement le shell manage.py

et ensuite

from rest_framework.authtoken.models import Token
from django.contrib.auth.models import User
u = User.objects.get(username='admin')
token = Token.objects.create(user=u)
print token.key

alors un enregistrement devrait être trouvé dans la table DB_Schema.authtoken_token

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X