Saltar al contenido

Generación de token de acceso único con Django OAuth2 Toolkit

Solución:

Si desea eliminar todos los tokens de acceso anteriores antes de emitir uno nuevo, existe una solución simple para este problema: ¡Crea tu propio proveedor de vistas de token!

El código a continuación probablemente lo ayudará a lograr ese tipo de funcionalidad:

from oauth2_provider.models import AccessToken, Application
from braces.views import CsrfExemptMixin
from oauth2_provider.views.mixins import OAuthLibMixin
from oauth2_provider.settings import oauth2_settings

class TokenView(APIView, CsrfExemptMixin, OAuthLibMixin):
    permission_classes = (permissions.AllowAny,)

    server_class = oauth2_settings.OAUTH2_SERVER_CLASS
    validator_class = oauth2_settings.OAUTH2_VALIDATOR_CLASS
    oauthlib_backend_class = oauth2_settings.OAUTH2_BACKEND_CLASS

    def post(self, request):
        username = request.POST.get('username')
        try:
            if username is None:
                raise User.DoesNotExist
            AccessToken.objects.filter(user=User.objects.get(username=username), application=Application.objects.get(name="Website")).delete()
        except Exception as e:
            return Response(e.message,status=400)

        url, headers, body, status = self.create_token_response(request)
        return Response(body, status=status, headers=headers)

La parte que debe notar es el bloque Try-Except. Allí encontramos los tokens de acceso y los eliminamos. Todo antes de crear uno nuevo.

Puede ver cómo crear su propio proveedor utilizando OAuthLib. Además, esto también podría ser útil: TokenView en django-oauth-toolkit. Puede ver allí el Apiview original. Como dijiste, estabas usando este paquete.

En cuanto a refresh_token, como se mencionó anteriormente en otras respuestas aquí, no puede hacer lo que está pidiendo. Al mirar el código de oauthlib tipo gruñido de contraseña, verá que en su inicialización, refresh_token se establece en True. A menos que cambie el tipo de Grunt, no se puede hacer.

Pero puede hacer lo mismo que hicimos anteriormente con los tokens de acceso. Cree el token y luego elimine el token de actualización.

Lo que necesito es que cada vez que un usuario solicite un nuevo token de acceso, el anterior se volverá inválido, inutilizable y será eliminado.

Dar una nueva ficha cuando la pides parece un comportamiento esperado. ¿No es posible que revoque el existente antes de solicitar el nuevo?

Actualizar


Si está decidido a conservar solo un token, la clase OAuth2Validator hereda OAuthLib’s RequestValidator y anula el método save_bearer_token. En este método, antes del código relacionado con la creación de la instancia del modelo AccessToken y su método .save (), puede consultar (similar a este) para ver si ya hay un AccessToken guardado en la base de datos para este usuario. Si se encuentra, el token existente se puede eliminar de la base de datos.

Le sugiero encarecidamente que haga este cambio configurable, en caso de que cambie de opinión en el futuro (después de que se emitan todos los tokens múltiples por razones como esta)

Una solución más simple es tener su propia clase de validación, probablemente una que herede oauth2_provider.oauth2_validators.OAuth2Validator y anula save_bearer_token. Esta nueva clase debe darse para OAUTH2_VALIDATOR_CLASS en settings.py


Además, ¿hay alguna manera de que el tipo gruñido de contraseña no cree un token de actualización? No tengo ningún uso para eso en mi aplicación.

Django OAuth Toolkit depende de OAuthLib.

Hacer que refresh_token sea opcional se reduce a create_token método en BearerToken class de oAuthLib en esta línea y la clase para la concesión de contraseña está aquí. Como puede ver el __init__ el método para esta clase toma refresh_token argumento que por defecto se establece en True. Este valor se utiliza en create_token_response método de la misma clase en la línea

token = token_handler.create_token(request, self.refresh_token)

create_token_response método en OAuthLibCore la clase del kit de herramientas Django OAuth es la que, creo, llama al correspondiente create_token_response en OAuthLib. Observe el uso de self.server y su inicialización en __init__ método de esta clase, que solo tiene el validador pasado como argumento, pero nada relacionado con refresh_token.

Compare esto con el tipo de concesión implícita de OAuthLib create_token_response método, que explícitamente hace

token = token_handler.create_token(request, refresh_token=False)

no crear refresh_token en absoluto

Entonces, a menos que me haya perdido algo aquí, tldr, No creo que el kit de herramientas de Django OAuth exponga la característica de opcional refresh_token.

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *