web-dev-qa-db-fra.com

Django Authentification par jeton de la structure restante)

J'ai lu les Django Rest Framework et fait tous les tutoriels. Tout semblait avoir du sens et fonctionnait exactement comme il se doit. J'ai obtenu l'authentification de base et de session fonctionnant comme décrit. http : //Django-rest-framework.org/api-guide

Cependant, je me bats avec la partie authentification par jeton de la documentation, elle manque un peu ou n’approfondit pas autant que les didacticiels.
http://Django-rest-framework.org/api-guide/authentication/#tokenauthentication

Il indique que je dois créer des jetons pour les utilisateurs, mais indique-t-il où, dans models.py?

Ma question est:

Quelqu'un peut-il expliquer la partie authentification de jeton de la documentation un peu mieux pour une première minuterie?

70
Prometheus

Non, pas dans votre models.py - Du côté des modèles, tout ce que vous avez à 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 est de décider quand et comment ces objets de jeton doivent être créés. Dans votre application, chaque utilisateur reçoit-il automatiquement un jeton? Ou seulement certains utilisateurs autorisés? Ou seulement quand ils en demandent spécifiquement un?

Si chaque utilisateur doit toujours avoir un jeton, il y a un extrait de code sur la page vers laquelle vous êtes lié qui explique comment configurer un signal pour le 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)

(mettez this dans un fichier models.py, n'importe où, et il sera enregistré quand un thread Django démarre)

Si les jetons ne doivent être créés qu’à certaines heures, 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.

61
Ian Clelland

@ ian-clelland a déjà fourni la bonne réponse. Il y a juste quelques petites pièces qui n'étaient pas mentionnées dans son post, donc je vais documenter toutes les procédures (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 ne fait pas créer son jeton.

  2. Allez à settings.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 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)
    

    Sinon, si vous voulez être plus explicite, créez un fichier nommé signs.py sous myapp projet. Mettez le code ci-dessus dessus, puis dans __ init __. Py , écrivez import signals

  4. Ouvrez une fenêtre de console, accédez au répertoire de votre projet et entrez la commande suivante:

    python manage.py migrate
    python manage.py makemigrations
    

    Jetez un coup d’œil dans votre base de données, une table nommée authtoken_token devrait être créée avec les champs suivants: clé (il s’agit de la valeur du jeton), créée (date/heure) il a été créé), user_id (une clé étrangère qui référence la colonne id de la table auth_user)

  5. créer un superutilisateur avec python manage.py createsuperuser. Maintenant, jetez un oeil à la table authtoken_token dans votre base de données avec select * from authtoken_token;, vous devriez voir qu'une nouvelle entrée a été ajoutée.

  6. En utilisant 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. 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 ):

    Authorization: Token your_token_value
    
  7. (Facultatif) DRF permet également de renvoyer le jeton d'un utilisateur si vous indiquez le nom d'utilisateur et le mot de passe. Tout ce que vous avez à faire est d’inclure les éléments suivants dans urls.py :

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

    Utiliser 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!

77
Cheng

Le Django 1.8.2 et le reste du framework 3.3.2 suivants n’ont pas suffi pour permettre l’authentification par jeton.

Bien que le paramètre REST_FRAMEWORK soit spécifié dans Django, des vues basées sur les fonctions sont requises @ 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.

14
Super S

Pour ajouter mes deux cents à cela, 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 de la manière suivante:

from rest_framework.authtoken.models import Token
# Other imports

class UserManager(BaseUserManager):

    def create_user(self, **whatever_else):
        """
        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(**whatever_params)
        .... #Method ramblings that somehow gave us a user instance
        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(**activation_ramblings):
        .... #Method ramblings that somehow gave us a user instance
        Token.objects.create(user=user)

Si vous avez déjà créé des utilisateurs, vous pouvez alors accéder au shell python de votre terminal) et créer des jetons pour tous les utilisateurs de votre base de données.

>>>from *whatever import User
>>>from rest_framework.authtoken.models import Token 
>>>for user in User.objects.all():
>>>...    Token.objects.create(user=user)

C'est tout ce qu'elle a écrit aux gens! J'espère que ça aide quelqu'un.

13
parsenz

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

il suffit de lancer le shell manage.py

et alors

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

9

Outre les excellentes réponses fournies ici, j'aimerais mentionner une meilleure approche de l'authentification par jeton: l'authentification par jeton Web JSON. La mise en oeuvre proposée par http://getblimp.github.io/Django-rest-framework-jwt/ est très facile à utiliser.

Les avantages sont expliqués plus en détail dans cette réponse .

5
Def_Os