8

Ho un servizio Django riposo di base, cheCome posso rendere il token di ritorno django-rest-framework-jwt alla registrazione?

  1. registra una persona e
  2. aggiorna la sua password.

Voglio aggiungere l'autenticazione jwt su di esso. Se seguo il tutorial, dovrei aggiungere un nuovo url chiamato "api-token-auth" nel progetto urls.py. Ma, non voglio aggiungere questo nuovo url e voglio che la mia chiamata di registro invii un token in risposta.

Ecco il mio codice:

serializers.py

class UserSerializer(serializers.HyperlinkedModelSerializer): 
    def create(self, validated_data): 
     user = User(
      username=validated_data['username'] 
     ) 
     user.set_password(validated_data['password']) 
     user.save() 
     return user 

    def update(self, instance, validated_data): 
     instance.set_password(validated_data['password']) 
     instance.save() 
     return instance 

    class Meta: 
     model = User 
     fields = ('url', 'username', 'password') 
     lookup_field = 'username' 
     write_only_fields = ('password',) 

views.py

class UserViewSet(viewsets.ModelViewSet): 
    """ 
    API endpoint that allows users to be viewed or edited. 
    """ 
    queryset = User.objects.exclude(is_superuser=1) 
    serializer_class = UserSerializer 
    lookup_field = 'username' 
  1. Che cosa dovrebbe essere fatto per raggiungere questo obiettivo? dovrei chiamare api-auth-token all'interno del metodo di creazione del mio serializzatore?
  2. In che modo django-rest-framework-jwt gestisce più token di autenticazione e identifica correttamente quale token appartiene a quale utente? Soprattutto quando non memorizza i token in un db.
  3. Come posso utilizzare questo meccanismo di autenticazione per limitare il mio utente a visualizzare/aggiornare/eliminare solo il suo utente?
  4. Come posso utilizzare questo meccanismo di autenticazione per fare qualcosa in generale. Ad esempio se un utente vuole scrivere il suo nome in /tmp/abcd.txt. Come posso assicurarmi che solo gli utenti autenticati siano in grado di farlo?
  5. Esistono potenziali scappatoie in questo approccio. Devo usare lo stesso codice se la mia app sta per memorizzare molti dati classificati?

risposta

12

Domanda 1: Per creare un token che avrebbe lavorato con django-resto-quadro-JWT è possibile utilizzare una funzione che assomiglia a:

import jwt 
from rest_framework_jwt.utils import jwt_payload_handler 

def create_token(user): 
    payload = jwt_payload_handler(user) 
    token = jwt.encode(payload, settings.SECRET_KEY) 
    return token.decode('unicode_escape') 

è possibile aggiungere questa funzione per la vista e creare il token una volta che l'utente è stato registrato.

Domanda 2: i token JWT non hanno bisogno di essere conservati int database che mi può leggere su come JWT funziona a http://jwt.io/

Domanda 3 e 4: per utilizzare i token per limitare l'accesso ad una vista specifica in particolare un APIView o di una delle sue sottoclassi o una vista forniti dal framework Django resto è necessario specificare il permission classes ad esempio

from rest_framework.permissions import IsAuthenticated 
from rest_framework.response import Response 
from rest_framework.views import APIView 

class ExampleView(APIView): 
    permission_classes = (IsAuthenticated,) 

    def get(self, request, format=None): 
     content = { 
      'status': 'request was permitted' 
     } 
     return Response(content) 

domanda 5: un potenziale feritoie mentre si lavora con Django Resto quadro è le autorizzazioni predefinite che si imposta dalla impostazioni della tua applicazione, se per esempio tu allowAll nelle impostazioni rende tutte le viste accessibili pubblicamente a meno che non si sovrascriva specificatamente le classi di autorizzazione.

1

La risposta accettata ha un codice che genera token ma non mostra come integrarlo in serializzatore/vista.Inoltre, non sono sicuro che il manuale jwt.encode è buon modo moderno se abbiamo già jwt_encode_handler Per fare questo è possibile creare SerializerMethodField e creare token di lì:

token = serializers.SerializerMethodField() 

def get_token(self, obj): 
    jwt_payload_handler = api_settings.JWT_PAYLOAD_HANDLER 
    jwt_encode_handler = api_settings.JWT_ENCODE_HANDLER 

    payload = jwt_payload_handler(obj) 
    token = jwt_encode_handler(payload) 
    return token 

Quindi aggiungere token campo per Meta.fields. Per l'esempio completo, fare riferimento a here

Problemi correlati