tutorial sessionauthentication revoke password framework auth python django oauth-2.0 django-rest-framework django-oauth

python - sessionauthentication - Generar token de acceso único con Django OAuth2 Toolkit



django-rest-auth (2)

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

El siguiente código probablemente lo ayude 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 deberías 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 podría ser útil también: TokenView en django-oauth-toolkit . Puedes 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 puedes hacer lo que estás preguntando. Al mirar el código del oauthlib contraseña de contraseña de oauthlib , 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 puedes hacer lo mismo que hicimos anteriormente con los tokens de acceso. Crea el token y luego borra el token de actualización.

Estoy utilizando el último kit de herramientas Django OAuth2 (0.10.0) con Python 2.7, Django 1.8 y Django REST framework 3.3

Al utilizar grant_type=password , noté un comportamiento extraño que cada vez que el usuario solicita un nuevo token de acceso:

curl -X POST -d "grant_type=password&username=<user_name>&password=<password>" -u"<client_id>:<client_secret>" http://localhost:8000/o/token/

Se crea un nuevo token de acceso y token de actualización. ¡El antiguo token de acceso y actualización aún se puede usar hasta el tiempo de espera del token!

Mis problemas:

  • Lo que necesito es que cada vez que un usuario solicite un nuevo token de acceso, el anterior se vuelva inválido, inutilizable y se elimine.
  • Además, ¿hay alguna manera de que el tipo de contraseña no cree token de actualización? No tengo ningún uso para eso en mi aplicación.

Una solución que encontré es que REST Framework OAuth proporciona una configuración para One Access Token a la vez. No estoy ansioso por usar ese proveedor, pero es posible que no tenga otra opción.


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

Dar un nuevo token cuando lo pida parece ser un comportamiento esperado. ¿No es posible revocar el existente antes de solicitar el nuevo?

Actualizar

Si está decidido a conservar solo un token: la clase OAuth2Validator hereda el RequestValidator de OAuthLib 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 esto ) 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.

Recomiendo encarecidamente que este cambio se pueda configurar, en caso de que cambies de opinión en el futuro (después de que se hayan emitido varios tokens por razones como esta )

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

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

Django OAuth Toolkit depende de OAuthLib.

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

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

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

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

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

para 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 refresh_token opcional.