Tengo una pregunta relacionada con Django. Estoy usando Knox Token Authentication para generar tokens para cada usuario cuando inicia sesión en la página.
Ahora quiero usar ese token para cada solicitud que se envíe para poder obtener el usuario correspondiente para el token. También estoy usando el def dashboard(request) en Django para cada ruta de URL.
He visto en youtube que hay una opción para obtener un usuario del token pero no tiene funciones
class UserAPI(generics.RetrieveAPIView): permission_classes = [ permissions.IsAuthenticated, ] serializer_class = UserSerializer def get_object(self): return self.request.userEntonces, ¿hay un suero para obtener el usuario correspondiente de un token dentro de una función personalizada?
Genial, descubrí en horas que Knox no viene con token_key completo almacenado en la base de datos.
El token real que podemos obtener es algo como: a512529e7ffceaa8406ceb616d088b3422ad15811a5eb470e8f4c4896c9aa649
En la base de datos token_key se almacena por defecto a512529e . 8 dígitos
Filtra objetos usando esto:
knox_object = AuthToken.objects.filter(token_key__startswith=token[:8]).first() Luego obtenga el objeto de usuario knox_object.user.username
O puedes usar esto, más rápido
from knox.settings import CONSTANTS knox_object = AuthToken.objects.filter(token_key=token[:CONSTANTS.TOKEN_KEY_LENGTH]).first()De los códigos fuente de Knox
class CONSTANTS: ''' Constants cannot be changed at runtime ''' TOKEN_KEY_LENGTH = 8 DIGEST_LENGTH = 128 SALT_LENGTH = 16 def __setattr__(self, *args, **kwargs): raise Exception(''' Constant values must NEVER be changed at runtime, as they are integral to the structure of database tables ''') CONSTANTS = CONSTANTS() Puede ver que TOKEN_KEY_LENGTH tiene 8 dígitos.
Escribí una función simple para hacer eso.
from knox.models import AuthToken from knox.settings import CONSTANTS def get_user_from_token(token): objs = AuthToken.objects.filter(token_key=token[:CONSTANTS.TOKEN_KEY_LENGTH]) if len(objs) == 0: return None return objs.first().userLa vida sea más fácil ahora. :)
Puedes probar mi tenedor. Si simplemente desea agregar @smart_token_user antes de cualquier método GET/POST/PUT/...
https://github.com/xros/django-resto-knox
Simplemente git clone y pip install ./
Escribí un decorador.
Con esto, en nuestra aplicación views.py podemos obtener fácilmente el objeto de usuario al hacerlo, @smart_token_user modificará el controlador de solicitudes. Podemos tener un atributo request.user solo una vez que el token sea válido. Y todos los intentos no válidos se descartarán con una respuesta HTTP 401 no autorizada. La vida puede ser más fácil con este decorador.
from knox.models import smart_token_user class CheckUserEmail(generics.RetrieveAPIView): permission_classes = (IsAuthenticated,) @smart_token_user def get(self, request): return Response({ "username": request.user.username, "email": request.user.email, "password": request.user.password, }, status=status.HTTP_200_OK) O use esto como original si quiere: authentication_classes = (TokenAuthentication,)
class CheckUserEmail(generics.RetrieveAPIView): authentication_classes = (TokenAuthentication,) permission_classes = (IsAuthenticated,) def get(self, request): return Response({ "username": request.user.username, "email": request.user.email, "password": request.user.password, }, status=status.HTTP_200_OK)